Search Unity

How can I switch text on TextMesh on some GameObjects using StartCoroutine ?

Discussion in 'Scripting' started by DubiDuboni, Sep 1, 2019.

  1. DubiDuboni

    DubiDuboni

    Joined:
    Feb 5, 2019
    Posts:
    131
    This script is attached to one empty GameObject :

    objectsTexts are just 3 GameObjects that I'm getting the names of them and use this names as the new text to switch to.

    objectsWithText are already GameObjects that have the TextMesh component attached.

    For example if on objectsWithText[0] the text is "Hello" and the name is objectsTexts[0] is "Hello World"
    Then I want to switch with fade in/out the text from "Hello" to "Hello World"

    The problem is that it's changing the text only for the objectsWithText and not for all the others.
    In this case there is 3 objectsWithTexts and 3 objectsTexts.

    I used a breakpoint and see that both objectsTexts and objectsWithTexts contains 3 objects on this line :

    Code (csharp):
    1.  
    2. StartCoroutine(UpdateDisplayPhrase(objectsTexts[i].name, objectsWithText[i].GetComponent<TextMesh>()));
    3.  
    But still it's switching only the first objects and not the rest two.

    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. public class SwitchMenuText : MonoBehaviour
    7. {
    8.     public GameObject[] objectsTexts;
    9.  
    10.     private bool isDisplaying;
    11.     private Vector3[] lastFwd;
    12.     private float curAngleX = 0;
    13.     private GameObject[] objectsWithText;
    14.  
    15.     public void Init()
    16.     {
    17.         objectsWithText = GameObject.FindGameObjectsWithTag("ObjectToAddText");
    18.         lastFwd = new Vector3[objectsWithText.Length];
    19.         for(int i = 0; i < objectsWithText.Length; i++)
    20.         {
    21.             lastFwd[i] = objectsWithText[i].transform.forward;
    22.         }
    23.     }
    24.  
    25.     private void Update()
    26.     {
    27.         for (int i = 0; i < objectsWithText.Length; i++)
    28.         {
    29.             var curFwd = objectsWithText[i].transform.forward;
    30.             // measure the angle rotated since last frame:
    31.             var ang = Vector3.Angle(curFwd, lastFwd[i]);
    32.  
    33.             if (myApproximation(ang, 179f, 1f) == true)
    34.             {
    35.                 StartCoroutine(UpdateDisplayPhrase(objectsTexts[i].name, objectsWithText[i].GetComponent<TextMesh>()));
    36.             }
    37.         }
    38.     }
    39.  
    40.     private bool myApproximation(float a, float b, float tolerance)
    41.     {
    42.         return (Mathf.Abs(a - b) < tolerance);
    43.     }
    44.  
    45.     private IEnumerator UpdateDisplayPhrase(string text, TextMesh t)
    46.     {
    47.         // block multiple calls
    48.         if (isDisplaying) yield break;
    49.  
    50.         isDisplaying = true;
    51.  
    52.         // you can simply yield IEnumerators so they are executed and at the same time
    53.         // wait until finished
    54.         yield return StartCoroutine(FadeTextTo(0, 0.6f, t));//FadeTextToZeroAlpha(1, t);
    55.  
    56.         t.text = text;
    57.  
    58.         // NOTE: you pass in 0
    59.         // -> DIVIDING BY 0 ?!
    60.         yield return StartCoroutine(FadeTextTo(1, 0.6f, t));//FadeTextToFullAlpha(0, t);
    61.  
    62.         // when done reset the blocking flag
    63.         isDisplaying = false;
    64.     }
    65.  
    66.     public IEnumerator FadeTextTo(float targetAlpha, float maxDuration, TextMesh textMesh)
    67.     {
    68.         // more efficient to get both colors beforehand
    69.         var fromColor = textMesh.color;
    70.         var toColor = new Color(fromColor.r, fromColor.g, fromColor.b, targetAlpha);
    71.  
    72.         // this is optional ofcourse but I like to do this in order to
    73.         // always have the same fading speed even if it is already slightly faded into one direction
    74.         var actualDuration = maxDuration * Mathf.Abs(fromColor.a - toColor.a);
    75.  
    76.         var passedTime = 0f;
    77.         while (passedTime < actualDuration)
    78.         {
    79.             var lerpFactor = passedTime / actualDuration;
    80.             // now the huge advantage is that you can add ease-in and -out if you like e.g.
    81.             //lerpFactor = Mathf.SmoothStep(0, 1, lerpFactor);
    82.  
    83.             textMesh.color = Color.Lerp(fromColor, toColor, lerpFactor);
    84.  
    85.             // avoid overshooting
    86.             passedTime += Mathf.Min(Time.deltaTime, actualDuration - passedTime);
    87.             yield return null;
    88.         }
    89.  
    90.         // just to be sure in the end always set it once
    91.         textMesh.color = toColor;
    92.     }
    93. }
    94.  
    And I'm calling the Init method in this script :

    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.UI;
    6. using TMPro;
    7.  
    8. public class AddTextToObject : MonoBehaviour
    9. {
    10.     public UnityEngine.GameObject[] objectsToNumber;
    11.     public UnityEngine.GameObject text;
    12.     public float yPadding;
    13.     public bool rotateNumbers = false;
    14.     public float rotationSpeed = 10f;
    15.     public bool textAbove = false;
    16.     public bool textInFront = false;
    17.     public bool textOnFaces = false;
    18.     public SwitchMenuText switchmenutext;
    19.  
    20.     private List<GameObject> newTexts = new List<GameObject>();
    21.     private MeshRenderer[] renderer;
    22.     private Vector3 newPos;
    23.     private GameObject newText;
    24.  
    25.     private void Start()
    26.     {
    27.         renderer = new MeshRenderer[objectsToNumber.Length];
    28.  
    29.         for (int i = 0; i < objectsToNumber.Length; i++)
    30.         {
    31.             newText = Instantiate(text);
    32.             renderer[i] = newText.GetComponent<MeshRenderer>();
    33.  
    34.             if (textAbove == true)
    35.             {
    36.                 newPos = new Vector3
    37.                 (
    38.                  objectsToNumber[i].transform.position.x,
    39.                  ((objectsToNumber[i].transform.position.y + renderer[i].bounds.extents.y) + yPadding),
    40.                    objectsToNumber[i].transform.position.z
    41.                  );
    42.             }
    43.  
    44.             if (textInFront == true)
    45.             {
    46.                 newPos = new Vector3
    47.                 (
    48.                  ((objectsToNumber[i].transform.position.x + renderer[i].bounds.extents.x) + yPadding),
    49.                  objectsToNumber[i].transform.position.y,
    50.                    objectsToNumber[i].transform.position.z
    51.                  );
    52.             }
    53.  
    54.             newText.transform.position = newPos;
    55.             newText.transform.parent = objectsToNumber[i].transform;//transform;
    56.             newText.name = objectsToNumber[i].name + " Text";
    57.             newText.tag = "ObjectToAddText";
    58.             newTexts.Add(newText);
    59.             var textmesh = newText.GetComponent<TextMesh>();
    60.  
    61.             if (textAbove == true)
    62.             {
    63.                 textmesh.text = i.ToString();
    64.             }
    65.  
    66.             if (textInFront == true)
    67.             {
    68.                 textmesh.text = objectsToNumber[i].name;
    69.             }
    70.         }
    71.  
    72.         switchmenutext.Init();
    73.     }
    74.  
    75.     private void Update()
    76.     {
    77.         if (rotateNumbers == true)
    78.         {
    79.             for (int i = 0; i < newTexts.Count; i++)
    80.             {
    81.                 newTexts[i].transform.Rotate(Vector3.up, 10 * rotationSpeed * Time.deltaTime);
    82.             }
    83.         }
    84.     }
    85. }
    86.  
     
    Last edited: Sep 1, 2019
  2. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    pretty sure that's the problem you have..

    Code (CSharp):
    1.         // block multiple calls
    2.         if (isDisplaying) yield break;
    3.         isDisplaying = true;
    4.  
    why not send the whole array and work on the entire array in one coroutine instead of starting a coroutine for each element?
     
    DubiDuboni likes this.