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. Dismiss Notice

AI state machine changes but all movement stops

Discussion in 'Scripting' started by aaeriam, Jun 21, 2016.

  1. aaeriam

    aaeriam

    Joined:
    Sep 17, 2014
    Posts:
    10
    I'm working on a simple AI state machine where I have 4 "characters" that walk around their own set of 4 waypoints (stored in an serialized array). The characters navigate through these points almost perfectly by themselves; however, I'm trying to build in a "Pause State" that allows me to stop the movement of the AI while the rest continue on their own way.

    Code (CSharp):
    1.     void SetState(GuardStates nextState)
    2.     {
    3.         lastState = curState;
    4.         if (nextState != curState)
    5.         {
    6.             curState = nextState;
    7.             //Debug.Log("Current state" + curState);
    8.         }
    9.     }
    10.  
    11.     public void StatePatrol ()
    12.     {
    13.         //GameObject.Find("Guard").GetComponent<Renderer>().material.color = Color.green;
    14.         Vector3 newTravelPosition = myNavPoints[navIndex].transform.position;
    15.         myNavAgent.SetDestination(newTravelPosition);
    16.  
    17.         if(myNavAgent.transform.position == newTravelPosition)
    18.         {
    19.             SetState(GuardStates.IDLE);
    20.         }
    21.     }
    22.  
    23.     public void StateIdle ()
    24.     {
    25.         //GameObject.Find("Guard").GetComponent<Renderer>().material.color = Color.cyan;
    26.  
    27.         myTimer += Time.deltaTime;
    28.  
    29.         if (myTimer >= maxTime)
    30.         {
    31.             SetState(GuardStates.PATROL);
    32.             myTimer = 0f;
    33.         }
    34.     }
    35.  
    36.     public void StatePause ()
    37.     {
    38.         SetState(GuardStates.PAUSE);
    39.         GetComponent<Renderer>().material.color = Color.gray;
    40.         myNavAgent.SetDestination(this.transform.position);
    41.         isPaused = true;
    42.     }
    here's the relevant part of my C# statemachine script. Basically, the patrol and idle states work pretty fine by themselves. When I press 1 (in my DebugManager script) it changes the active character's state to Pause and I have an exit pause function in the state machine that's run in the Update function of the state machine to exit the Pause state when the conditions are met.
    (like so)

    Code (CSharp):
    1.     void ExitPause ()
    2.     {
    3.         if (Input.GetKeyDown(KeyCode.Alpha1) && isPaused == true && curState == GuardStates.PAUSE)
    4.         {
    5.             SetState(lastState);
    6.         }
    7.     }
    When I press 1 to un-pause the game, the states continue to change between Idle and Patrol for the active character; however, the character doesn't actually move at all. The scripts aren't huge but the post is already pretty long. If need be, I can post the complete statemachine and debugmanager scripts.
     
  2. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    So, you verified that the state that you come back to is patrol/idle?

    If I am reading this correctly, every time that you run the StatePause, it sets the last state to pause, so when you return it to the last state by unpausing, it sets it back to pause.

    Next question, is Pause supposed to pause the entire scene? If so, pause is a time based thing. When doing movement or any calculation, Time.timeScale should be referenced.

    Past this, I would have to see the entire code to tell you what the problem is.
     
  3. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,181
    So I saw this:

    Code (csharp):
    1.     void SetState(GuardStates nextState)
    2.     {
    3.         lastState = curState; //This can't be right!
    4.         if (nextState != curState)
    5.         {
    6.             curState = nextState;
    7.             //Debug.Log("Current state" + curState);
    8.         }
    9.     }
    You're setting the last state even if you don't update the state! So if you're in patrol, and try to set to patrol, both current and last state will be patrol.

    I can't tell what your problem is either, but this might be it?
     
    LeftyRighty likes this.
  4. jimroberts

    jimroberts

    Joined:
    Sep 4, 2014
    Posts:
    560
    Did you set the destination back to what it was before you paused and set isPaused to false? Baste is right about SetState as well. lastState should only be set if you can update the curState.
    Code (CSharp):
    1. void SetState(GuardStates nextState)
    2. {
    3.     if (nextState != curState)
    4.     {
    5.         lastState = curState;
    6.         curState = nextState;
    7.         //Debug.Log("Current state" + curState);
    8.     }
    9. }