Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Sequence with coroutines.

Discussion in 'Scripting' started by tmanallen, Mar 15, 2014.

  1. tmanallen

    tmanallen

    Joined:
    Nov 8, 2009
    Posts:
    395
    Quick question for the forums, I have combos in which if you hit certain objects within the time then you get bonus points the only thing I can't figure out is how to do it in sequence.

    Code (csharp):
    1.  
    2.  IEnumerator ComboOne()
    3.     {
    4.  
    5.          if (Target1.Hit == true)
    6.                 yield return new WaitForSeconds(3);
    7.             if (Target2.Hit == true)
    8.                yield return new WaitForSeconds(3);
    9.                 if (Target3.Hit == true)
    10.                 StartCoroutine(Anna());
    11. }
    12.  
    13.  
    The problem is when I hit them in any order they still do the same thing, so just needing to know how to hit in a sequence order?


    Thanks
     
    Last edited: Mar 15, 2014
  2. laurelhach

    laurelhach

    Joined:
    Dec 1, 2013
    Posts:
    229
    This is actually what you have :
    So they are all checked at the same time. It will check for Target1, then 2 and then 3.
    Code (csharp):
    1.  
    2.  IEnumerator ComboOne(){
    3.  
    4.          if (Target1.Hit == true)
    5.                 yield return new WaitForSeconds(3);
    6.          if (Target2.Hit == true)
    7.                yield return new WaitForSeconds(3);
    8.          if (Target3.Hit == true)
    9.                 StartCoroutine(Anna());
    10. }
    11.  
    If you want to force 1 first, then the other :
    Code (csharp):
    1.  
    2.  IEnumerator ComboOne(){
    3.  
    4.     if (Target1.Hit == true){
    5.            yield return new WaitForSeconds(3);
    6.  
    7.            if (Target2.Hit == true){
    8.                 yield return new WaitForSeconds(3);
    9.  
    10.                 if (Target3.Hit == true){
    11.                      StartCoroutine(Anna());
    12.                 }
    13.            }
    14.       }
    15. }
    16.  
    You basically need to put the "{*}" sign in your if statement so they are sequential.
     
  3. tmanallen

    tmanallen

    Joined:
    Nov 8, 2009
    Posts:
    395
    Thanks for the reply, this what I did to solve this,

    Code (csharp):
    1.  
    2.      IEnumerator ComboOne(){
    3.      HitCount = 0
    4.         if (Target1.Hit == true){
    5.              HitCount = 1;
    6.                yield return new WaitForSeconds();
    7.                 HitCount = 0;
    8.                if (Target2.Hit == true  HitCount == 1){
    9.                       HitCount = 2;
    10.                        yield return new WaitForSeconds(3);
    11.                      HitCount = 0;
    12.            if (Target3.Hit == true  HitCount == 2){
    13.                          StartCoroutine(());
    14.                     }
    15.                }
    16.           }
    17.     }
    18.  
    Basically, it works but hopefully on one gets confused, when the Hit Count is set a specific Target, then as long as you are within the the time frame then HitCount increments and if you are 0 you must hit the first target to get past the hit count= 0 and then move forward, if that makes sense.
     
  4. laurelhach

    laurelhach

    Joined:
    Dec 1, 2013
    Posts:
    229
    Glad I could help!

    Did you try your code? Does it work?
    I have the feeling that after your first timer which has no time value btw, the next statement won't work:
    Code (csharp):
    1.  
    2. yield return new WaitForSeconds(); //no time here
    3. HitCount = 0; // you reset the HitCount which prevent the next statement to be True
    4.      if (Target2.Hit == true  HitCount == 1){ ...
    5.  
    You do it twice.

    Make sense?
     
  5. tmanallen

    tmanallen

    Joined:
    Nov 8, 2009
    Posts:
    395
    Actually it does work, I set my hit count to =0 and as long as I am within the time frame it executes perfectly.
    That is my bad I do add 3 seconds to execute the next code. Just forgot to show it here.
     
  6. illustir

    illustir

    Joined:
    Dec 12, 2014
    Posts:
    24
    The nesting looks terribly unwieldy. Any way to sequentially execute Coroutines within a certain context?
     
  7. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,384
    It depends on the context/conditions. You can certainly make more effective designs by altering how you think about conditions. The above *idea* is okay (doesn't work as is), but the formatting is extremely bad and there are piles of errors in the code.

    LINQ could possibly help clean it up in some cases. Sometimes you can do returns/breaks to exit the routine instead of nesting if's deeper and deeper. Sometimes its best to modularize the routines differently just for the sake of maintainability and readability.
     
  8. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    I tend to do this for sequences

    Code (CSharp):
    1. IEnumerator CoThingie (){
    2.     // Do something
    3.     while (!someCondition) yield return null;
    4.     // Do the next thing
    5. }
    You can also throw a timer inside the while and yield return break if there is no action within the time limit.