Search Unity

Passing the same struct to a coroutine as in a list and getting different results. Stumped.

Discussion in 'Scripting' started by TimBurnstone, Aug 23, 2020.

  1. TimBurnstone

    TimBurnstone

    Joined:
    Nov 16, 2012
    Posts:
    9
    Trying to fade a line of text for a text box I'm creating and I'm completely stumped. The Textline struct I pass to the coroutine fades out as expected, but the line I add to the list doesn't. I've truncated out the unnecessary bits of code and posted that here:

    The debug output at line 19 sticks at 255, while the debug output at line 38 counts down from 255 to 0. I'm confused, aren't these the same variable? Why am I getting different outputs?


    Code (CSharp):
    1. struct TextLine
    2. {
    3.     public string text;
    4.     public Color32 color;
    5.  
    6. }
    7. public class TextBox : MonoBehaviour
    8. {
    9.     private List<TextLine> textLines;
    10.  
    11.  
    12.     void Start()
    13.     {
    14.         textLines = new List<TextLine>();
    15.     }
    16.  
    17.     void Update()
    18.     {
    19.         if (textLines.Count != 0) Debug.Log(textLines[0].color.a);
    20.     }
    21.  
    22.     public void AddTextLine(string text, Color32 color)
    23.     {
    24.         TextLine newLine = new TextLine();
    25.         newLine.text = text;
    26.         newLine.color = color;
    27.         textLines.Add(newLine);
    28.         StartCoroutine(fadeLine(newLine));      
    29.     }
    30.  
    31.     private IEnumerator fadeLine(TextLine line)
    32.     {
    33.         yield return new WaitForSeconds(2f);
    34.  
    35.         for (float i = 255f; i > 0f; i-= Time.deltaTime * 128f)
    36.         {
    37.             line.color.a = (byte)i;
    38.             Debug.Log(line.color.a);
    39.             yield return null;
    40.         }
    41.         line.color.a = 0;
    42.     }
    43.  
    I'm sure there are better ways to do what I'm trying to accomplish, and I'm sure I can find a work-around. But at this point I'm too curious as to what the problem is.
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,909
    Structs are value types in C#. Value types are passed to functions "by value" which means a copy is made. So when you pass your TextLine into the coroutine you are passing only a copy of it, not the original. You can use a ref parameter to get around this, or turn your struct into a class instead.
     
  3. TimBurnstone

    TimBurnstone

    Joined:
    Nov 16, 2012
    Posts:
    9
    I can? I swear IEnumerators can't take refs.

    Edit: Also, thank you for the explanation.
     
  4. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,909
    Alternative is to turn your struct into a class.
     
    Kurt-Dekker likes this.
  5. TimBurnstone

    TimBurnstone

    Joined:
    Nov 16, 2012
    Posts:
    9
    Seems legit, I'll do that. Thanks again.