Search Unity

Feedback Trying to understand Coroutine

Discussion in 'Getting Started' started by aMIGA_dUDE, Apr 1, 2021.

  1. aMIGA_dUDE

    aMIGA_dUDE

    Joined:
    Oct 12, 2019
    Posts:
    22
    I have been trying to understand Coroutine's (yield) and this little bit of code has help me to be able understand a lot better by see what is really going on.

    yield is your friend. Do a little, a lot!

    Hopefully it will help others to understand what going on little better.

    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3.  
    4. public class coroutining : MonoBehaviour
    5. {
    6.     // A Corountine is called in this order
    7.     // In Physics is you use yield of "yield WaitForFixedUpdate" https://docs.unity3d.com/ScriptReference/WaitForFixedUpdate.html
    8.     // After FixedUpdate-Internal animation(1)-Internal Physics-Internal animation(2)-OnTrigerXXX-OnCollisionXXX
    9.     // Once that has all been done it will be called. It the very last thing in Physics.
    10.     // In Game Logic it called after Update
    11.     // depending on which yield you have done it will be called in this order after Update
    12.     // 1. "yield null"
    13.     // 2. "yield WaitForSeconds" https://docs.unity3d.com/ScriptReference/WaitForSeconds.html
    14.     // 3. "yield WWW"
    15.     // 4. yield StartCoCoutine
    16.     // Then will continual on with everything else within Game Logic.
    17.     // The one more place that is called in and that End of frame, it only thing that called there "yield WaitForEndOfFrame" https://docs.unity3d.com/ScriptReference/WaitForEndOfFrame.html
    18.     // yield is your friend. Do a little, a lot!
    19.     // https://docs.unity3d.com/Manual/ExecutionOrder.html
    20.  
    21.  
    22.     // Yes I know it makes a massive Debug.Log but it the only way I could think showing how effectiveness of Corountine is when using yields correctly,
    23.     // I just would not used them as often as I have for real. Do little bit more work first before call a yield.
    24.  
    25.     [SerializeField] float timerLength = 0.02f; //total length of duration, it creates a lot data even at this low amount of time.
    26.     [SerializeField] int runMethodMin = 0; // Which loop to start running Method upon
    27.     [SerializeField] int runMethodMax = 3; // Which loop to end running Method upon
    28.     [SerializeField] int runCoroutineA = 1; // Which loop to run this Coroutine that doesn't like using yield
    29.     [SerializeField] int runCoroutineBMin = 4;  // Which loop to start running Coroutine that uses a lot of yield
    30.     [SerializeField] int runCoroutineBMax = 9; // Which loop to end running Coroutine that uses a lot of yield
    31.     [SerializeField] int runCoroutineC = 6; // Which loop to run Coroutine that uses a lot of yield
    32.  
    33.     int masterLoop = 0;
    34.     int countCoroutine = 0;
    35.     bool isCoroutine = false;
    36.     bool waitingToExit = false;
    37.  
    38.     // Update is called once per frame
    39.     void Update()
    40.     {
    41.  
    42.         if(masterLoop==runCoroutineA)
    43.         {
    44.             SetUpCoroutineA(masterLoop);
    45.         }
    46.         if(masterLoop==runCoroutineC)
    47.         {
    48.             SetUpCoroutineC(masterLoop);
    49.         }
    50.  
    51.         if(masterLoop>=runMethodMin && masterLoop<=runMethodMax)
    52.         {
    53.             SetUpMethod(masterLoop);
    54.         }
    55.         if (masterLoop >= runCoroutineBMin && masterLoop <= runCoroutineBMax)
    56.         {
    57.             SetUpCoroutineB(masterLoop);
    58.         }
    59.  
    60.         if (masterLoop>runMethodMax && masterLoop>runCoroutineBMax)
    61.         {
    62.             if(!waitingToExit)
    63.             {
    64.                 Debug.Log("Waiting to EXIT");
    65.                 waitingToExit = true;
    66.             }
    67.             if(countCoroutine==0)
    68.             {
    69.                 GetMeOutOfHere();
    70.             }
    71.         }
    72.         masterLoop++;
    73.     }
    74.    
    75.  
    76.     private void SetUpMethod(int varref)
    77.     {
    78.         int instance = countCoroutine;
    79.         OutDataStream("Method", varref, 0,instance);
    80.         Method(varref, instance);
    81.     }
    82.  
    83.  
    84.     private void Method(int varref,int intance)
    85.     {
    86.         float timerStart = Time.realtimeSinceStartup + timerLength;
    87.         while (timerStart > Time.realtimeSinceStartup)
    88.         {
    89.             OutDataStream("Method", varref, 1,intance);
    90.  
    91.         }
    92.     }
    93.  
    94.     private void SetUpCoroutineA(int varref)
    95.     {
    96.         isCoroutine = true;
    97.         countCoroutine++;
    98.         int instance = countCoroutine;
    99.         OutDataStream("CoroutineA", varref, 0,instance);
    100.         StartCoroutine(CorourineA(varref,instance));
    101.        
    102.     }
    103.  
    104.     IEnumerator CorourineA(int varref,int instance)
    105.     {
    106.        
    107.         float timerStart = Time.realtimeSinceStartup + timerLength;
    108.         while (timerStart > Time.realtimeSinceStartup)
    109.         {
    110.             OutDataStream("CoroutineA", varref, 1, instance);
    111.  
    112.         }
    113.        
    114.         yield return null;
    115.        
    116.         timerStart = Time.realtimeSinceStartup + timerLength;
    117.         while (timerStart > Time.realtimeSinceStartup)
    118.         {
    119.             OutDataStream("CoroutineA", varref, 2, instance);
    120.  
    121.         }
    122.         isCoroutine = false;
    123.         countCoroutine--;
    124.     }
    125.  
    126. private void SetUpCoroutineB(int varref)
    127. {
    128.     countCoroutine++;
    129.     int instance = countCoroutine;
    130.     OutDataStream("CoroutineB", varref, 0,instance);
    131.     StartCoroutine(CorourineB(varref,instance));
    132.  
    133. }
    134.  
    135. IEnumerator CorourineB(int varref,int instance)
    136. {
    137.    
    138.     float timerStart = Time.realtimeSinceStartup + timerLength;
    139.     while (timerStart > Time.realtimeSinceStartup)
    140.     {
    141.         OutDataStream("CoroutineB", varref, 1, instance);
    142.         yield return null;
    143.     }
    144.  
    145.     yield return null;
    146.  
    147.     timerStart = Time.realtimeSinceStartup + timerLength;
    148.     while (timerStart > Time.realtimeSinceStartup)
    149.     {
    150.         OutDataStream("CoroutineB", varref, 2, instance);
    151.         yield return null;
    152.     }
    153.         countCoroutine--;
    154. }
    155.  
    156.     private void SetUpCoroutineC(int varref)
    157.     {
    158.         countCoroutine++;
    159.         int instance = countCoroutine;
    160.         isCoroutine = true;
    161.         OutDataStream("CoroutineC", varref, 0,instance);
    162.         StartCoroutine(CorourineC(varref,instance));
    163.  
    164.     }
    165.  
    166.     IEnumerator CorourineC(int varref,int instance)
    167.     {
    168.      
    169.         float timerStart = Time.realtimeSinceStartup + timerLength;
    170.         while (timerStart > Time.realtimeSinceStartup)
    171.         {
    172.             OutDataStream("CoroutineC", varref, 1, instance);
    173.             yield return null;
    174.         }
    175.  
    176.         yield return null;
    177.  
    178.         timerStart = Time.realtimeSinceStartup + timerLength;
    179.         while (timerStart > Time.realtimeSinceStartup)
    180.         {
    181.             OutDataStream("CoroutineC", varref, 2, instance);
    182.             yield return null;
    183.         }
    184.         isCoroutine = false;
    185.         countCoroutine--;
    186.     }
    187.  
    188.     private void OutDataStream(string varstring,int varref,int varrefsuffix,int instance)
    189.     {
    190.         // Development is what I use while creating this
    191.         // Human is in easier to read Human format
    192.         // CVS is just CVS versions because I can, it based upon the layout in Human
    193.         string outputDevlopment = $"{varref} {varrefsuffix} [{instance}:{countCoroutine}] {varstring}: {Time.realtimeSinceStartup} {isCoroutine}";
    194.         string outputHuman = $"Type: {varstring}-{varrefsuffix} Loop: {varref} Instance: {instance} TotalCotoutine: {countCoroutine} isCoroutine: {isCoroutine} Time: {Time.realtimeSinceStartup}";
    195.         string outputCVS = $"\"{varstring}\",{varrefsuffix},{varref},{instance},{countCoroutine},{(isCoroutine ? 1 : 0)},{Time.realtimeSinceStartup}";
    196.        
    197.         string output = outputHuman;
    198.         Debug.Log(output);
    199.     }
    200.  
    201.  
    202.  
    203.  
    204.     private void GetMeOutOfHere()
    205.     {
    206.         Debug.Log("It goodnight from me, and goodnight from him");
    207.  
    208. #if UNITY_EDITOR
    209.  
    210.         UnityEditor.EditorApplication.ExitPlaymode();
    211.         //UnityEditor.EditorApplication.ExitPlaymode = true;
    212.         //UnityEditor.EditorApplication.isPlaying = false;
    213.  
    214. #endif
    215.         Application.Quit();
    216.     }
    217. }
    218.  
    219.