Search Unity

State machine coroutine vs Update

Discussion in 'Scripting' started by TwiiK, Sep 3, 2011.

  1. TwiiK

    TwiiK

    Joined:
    Oct 23, 2007
    Posts:
    1,729
    I've been following Burgzergs hack slash tutorial and I was wondering why he uses a coroutine for his state machine instead of just putting it in Update(). Is that yield so important? I've never seen a state machine before so this may be a dumb question and my terminology and thread title may be off, but whatever. :)

    Basically, why write this:
    Code (csharp):
    1.  
    2. void Start() {
    3.     _state = AI.State.Init;
    4.     StartCoroutine("FSM");
    5. }
    6.  
    7. private IEnumerator FSM() {
    8.     while(_alive) {
    9.         switch(_state) {
    10.             case State.Init:
    11.                 Init();
    12.                 break;
    13.             case State.Setup:
    14.                 Setup();
    15.                 break;
    16.             case State.Search:
    17.                 Search();
    18.                 break;
    19.         }
    20.        
    21.         yield return null;
    22.     }
    23. }
    24.  
    Instead of this?
    Code (csharp):
    1.  
    2. void Start() {
    3.     _state = AI.State.Init;
    4. }
    5.  
    6. void Update() {
    7.     while(_alive) {
    8.         switch(_state) {
    9.             case State.Init:
    10.                 Init();
    11.                 break;
    12.             case State.Setup:
    13.                 Setup();
    14.                 break;
    15.             case State.Search:
    16.                 Search();
    17.                 break;
    18.         }
    19.     }
    20. }
    21.  
    Was originally going to ask Burg himself about it, but found no contact information on his site and I figured this was a general programming question.
     
  2. VanJones

    VanJones

    Joined:
    May 1, 2011
    Posts:
    34
    If you would put it in the Update and have to calculate something like a very long path, which can take some miliseconds, it would slow down every frame and your FPS would drop heavily.
    Coroutines don't affect the Standart Game Loop and allow calculations, which might take some time to be calculated, without worrying about FPS-drops.
     
  3. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Actually, no...you're talking about threads, but coroutines aren't threads. They are run in the same thread as all other functions and scripts, and if you have heavy calculations in a coroutine, it will cause the same performance hit. You can use real threads in Unity, but Unity functions aren't thread-safe, so when making threads you must use thread-safe .net functions only. Coroutines and threads work differently and have different purposes.

    Anyway, as far as this particular state machine code goes, there's no immediate practical difference between a coroutine and using Update. So I don't know why it's done like that. However, normally a FSM would be a good candidate for using a coroutine:

    Code (csharp):
    1. function FSM () {
    2.     while (alive) {
    3.         switch (state) {
    4.             case (State.Wander):
    5.                 yield Wander();
    6.                 break;
    7.             case (State.Chase):
    8.                 yield Chase();
    9.                 break;
    10.             case (State.Attack):
    11.                 yield Attack();
    12.                 break;
    13.             case (State.Retreat):
    14.                 yield Retreat();
    15.                 break;
    16.         }
    17.     }
    18. }
    In this case, Wander() and so on are also coroutines. So the actual state machine code would only run when the state changes (instead of every frame), and the rest of the time would be spent wandering/chasing/etc.

    --Eric
     
    NullableMug likes this.
  4. TwiiK

    TwiiK

    Joined:
    Oct 23, 2007
    Posts:
    1,729
    Ok, that makes sense.

    Burg obviously has way more programming experience than me so there may be more to that code than what I pasted or it's a work in progress. Either way I'll avoid this stuff until I actually need it. No need to confuse myself, unnecessarily. :)