• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
This question was closed Apr 05, 2022 at 11:34 PM by PresidentTree.
avatar image
Question by PresidentTree · Apr 01, 2022 at 12:58 AM · scripting problemif-statementsscript errordialogueelse if

Why is an else-if statement breaking my dialogue system?

A dialogue system I created uses a method called ReadLine() to type out the speaker's text like a typewriter. This method takes a string for the speaker's name, a string for the speaker's text, and an integer index to keep track of the conversation every time a key is pushed. However, when the speaker's name is null, the text does not get typed out when it is called for the first time. The problem seems to stem from the else-if statement within ReadLine(), but I am unable to figure out why as it has nothing to do with the speaker's name. Any help would be appreciated.

Dialogue Script:

 public class DialogueScript : MonoBehaviour
 {
     private Image dialogueBox;
     private TextMeshProUGUI nameBox;
     private TextMeshProUGUI textBox;
     private float textSpeed = 0.05f;
     private int textIndex;
 
     //Reference to dialogue box:
     void Start()
     {
         dialogueBox = GameObject.Find("Overlay").transform.GetChild(5).GetComponent<Image>();
         nameBox = dialogueBox.transform.GetChild(0).GetComponent<TextMeshProUGUI>();
         textBox = dialogueBox.transform.GetChild(1).GetComponent<TextMeshProUGUI>();
     }
 
     //Play dialogue:
     void Update()
     {
         OpenDialogueBox();
         ReadLine("Johnny", "I have a question!", 1);
         ReadLine(null, "Answer the question?", 2);
         ReadLine(null, "Are you sure?", 3);
         ReadLine("Roderick", "Ask away.", 4);
         CloseDialogueBox(5);
     }
 
     //Open dialogue box:
     void OpenDialogueBox()
     {
         if (!dialogueBox.gameObject.activeSelf && Input.GetKeyDown(KeyCode.T))
         {
             dialogueBox.gameObject.SetActive(true);
             nameBox.text = string.Empty;
             textBox.text = string.Empty;
             textIndex = 1;
         }
     }
 
     //Close dialogue box:
     void CloseDialogueBox(int closingIndex)
     {
         if (closingIndex == textIndex)
         {
             StopAllCoroutines();
             dialogueBox.gameObject.SetActive(false);
         }
     }
 
     //Types script to dialogue box:
     void ReadLine(string name, string text, int num)
     {
         text = "\"" + text + "\"";
 
         if (Input.GetKeyDown(KeyCode.T) && num == textIndex)
         {
             nameBox.text = name;
 
             if (textBox.text == text)
             {
                 textIndex++;
             }
             else if (textBox.text.Length < text.Length && textBox.text.Length > 0)
             {
                 StopAllCoroutines();
                 textBox.text = text;
             }
             else
             {
                 textBox.text = string.Empty;
                 StartCoroutine(TypeLine(name, text));
             }
         }
     }
 
     //Typewriter effect:
     IEnumerator TypeLine(string name, string text)
     {
         foreach (char letter in text)
         {
             textBox.text += letter;
             yield return new WaitForSeconds(textSpeed);
         }
     }
 }
Comment

People who like this

0 Show 0
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

  • Sort: 
avatar image

Answer by rh_galaxy · Apr 01, 2022 at 01:57 AM

This is only true at the frame when the key is first pressed. Not any time after that.

 Input.GetKeyDown(KeyCode.T)

The rest is also broken

 //if typewriter effect finished
 if (textBox.text == text)
 {
     textIndex++; //next text
     //but this will never happen because Input.GetKeyDown(KeyCode.T) is not true here
 }
 //if typewriter effect not finished and not at char 0
 else if (textBox.text.Length < text.Length && textBox.text.Length > 0)
 {
     StopAllCoroutines(); //so you stop the typewriter effect directly at char 1 which is wrong
     textBox.text = text; //typewriter effect set to finished
     //but this will never happen because Input.GetKeyDown(KeyCode.T) is not true here
 }
 //else (only happens at char 0)
 else
 {
     //so this is the only thing that runs
     textBox.text = string.Empty;
     StartCoroutine(TypeLine(name, text)); //start typewriter effect
     // and because you have no check for if the coroutine already runs you
     // start a coroutine again on each T-key press, but only if it is pressed
     // before the coroutine has set the first char of textBox.text.
     //you see here that the way you are doing it is not right, you must have
     // a state (isStarted, isDone)...
 }

You are also both setting textBox.text and checking textBox.text in the else-if block which makes it hard to understand what is happening.

I still think my last answer is correct and clean, but you have to add a keypress check for it to work like you want.

 //New state variables
 bool effectStarted = false;
 bool effectDone = false;
 
 //Types script to dialogue box:
 void ReadLine(string name, string text, int num)
 {
     if (num == textIndex)
     {
         text = "\"" + text + "\"";
         if (!effectStarted &&
             Input.GetKeyDown(KeyCode.T)) //this is new, check for keypress when effect not started
         {
             nameBox.text = name;
             effectStarted = true;
             effectDone = false;
             StartCoroutine(TypeLine(name, text));
         }
         else if(Input.GetKeyDown(KeyCode.T)) //update: this is new
         {
             textBox.text = text;
             StopAllCoroutines();
             effectDone = true;
         }
         if (effectDone)
         {
             textIndex++;
             effectStarted = false;
         }
     }
 }
 
 //Typewriter effect:
 IEnumerator TypeLine(string name, string text)
 {
     foreach (char letter in text)
     {
         textBox.text += letter;
         yield return new WaitForSeconds(textSpeed);
     }
     effectDone = true;
 }
Comment

People who like this

0 Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image PresidentTree · Apr 02, 2022 at 04:25 PM 0
Share

With the addition of the else-if statement, it only seems to work when textIndex can't continue, such as when CloseDialogueBox() is removed. Aside from that, the dialogue just jumps to the next speaker early instead of filling in textBox and then waiting for the player to continue to conversation. This happens even if an input key is added to the last if-statement.

avatar image

Answer by PresidentTree · Apr 01, 2022 at 03:25 PM

@rh_galaxy

Your code is working now. In the last thread, it didn't work because the input that prevented the text from playing continuously was removed, which confused me. However, the else-if statement was used to fill in the text box if the player did not want to wait for the typewriter. Since I shouldn't be stopping any coroutines while dialogue plays, how am I supposed to print out the text without causing TypeLine() to continue to type? If that is not possible, I will accept a way to speed up the typewriter while the same key input is held down.

Comment

People who like this

0 Show 0 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

237 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How do i change script in one scene without changing it in all the scenes 1 Answer

(Problem) Turning postprocessing on and off 0 Answers

SphereCast doesn't work when I increase the radius. 1 Answer

Error with pause menu script. 0 Answers

how to call a method from another script?,Does not contain a definition for and no accessible extension method accepting a first argument errors 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges