• 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
0
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. T$$anonymous$$s 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 wit$$anonymous$$n ReadLine(), but I am unable to figure out why as it has not$$anonymous$$ng 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.GetC$$anonymous$$ld(5).GetComponent<Image>();
         nameBox = dialogueBox.transform.GetC$$anonymous$$ld(0).GetComponent<TextMeshProUGUI>();
         textBox = dialogueBox.transform.GetC$$anonymous$$ld(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
Add comment
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
0

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

T$$anonymous$$s 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 t$$anonymous$$s 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 w$$anonymous$$ch is wrong
     textBox.text = text; //typewriter effect set to finished
     //but t$$anonymous$$s will never happen because Input.GetKeyDown(KeyCode.T) is not true here
 }
 //else (only happens at char 0)
 else
 {
     //so t$$anonymous$$s is the only t$$anonymous$$ng 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 w$$anonymous$$ch makes it hard to understand what is happening.

I still t$$anonymous$$nk 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)) //t$$anonymous$$s 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: t$$anonymous$$s 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
Add comment · 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
avatar image
0

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, w$$anonymous$$ch 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 w$$anonymous$$le 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 w$$anonymous$$le the same key input is held down.

Comment
Add comment · 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

Error CS0246: The type or namespace name 'SteamVR_TrackedObject' could not be found. Are you missing an assembly reference? 2 Answers

Help with script 1 Answer

[C#] Quaternion Rotations with Input.GetAxis problems. 1 Answer

Unity Dialogue System only active when NPC is in range? 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