Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • 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 at 11:34 PM by PresidentTree.
avatar image
0
Question by PresidentTree · Apr 01 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
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 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
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 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
0

Answer by PresidentTree · Apr 01 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
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

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

Resources.LoadAll Generates Cast exception Error 2 Answers

If two PlayerPrefs are on? 2 Answers

How to destroy player when collide with enemy? 3 Answers

get my scripts to talk to each other 2 Answers

Need help fixing my script 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