Search Unity

NavMeshAgent breaking when enabling/disabling

Discussion in 'Editor & General Support' started by NickXDStudios, Sep 23, 2014.

  1. NickXDStudios

    NickXDStudios

    Joined:
    Jul 8, 2014
    Posts:
    5
    Hey,
    I have implemented a state machine for the enemies in our game. The state machine is the typical FSM given that each state has a Enter, Execute and Exit function. The idea of our "WalkToTarget" state is as follows....

    Enter:
    Enable NavMeshAgent

    Execute:
    if agent position is far away from player
    make sure nav mesh is enabled
    set destination of nav mesh to be the target
    if there are any players in the arm length goto decision making state
    else
    make sure nav mesh is disabled as we want to move manually
    move towards the target position using Vector3.MoveTowards but make sure the y position remains constant with the previous transform.position.y
    If we have reached the destination goto decision making state

    Exit:
    Disable NavMeshAgent


    Now this works fine for the most part but then randomly the agent will just fall through the ground.... there is nothing complicated in my scene its just a flat ground plane (and yes ive mad sure the plane is a state nav mesh and have baked the navmesh)

    Incase its not clear: where it says "goto" in the about pseudo code is a state transition meaning it will call the 'Exit' function of the current state (in this case the WalkToTarget state decribed above) and then calls the enter function on the new state (not important for this example). Also, the Execute function is called in the Update function.

    Here is the code

    Variables:
    Code (CSharp):
    1.  
    2. //the target position to walk to
    3. private Transform _target = null;
    4. //offset to the player we want to stand
    5. private Vector3 _offset = Vector3.zero;
    6. //the nav of this enemy
    7. private NavMeshAgent _nav = null;
    8.  
    Enter:
    Code (CSharp):
    1.  
    2. public override void Enter()
    3. {
    4.     base.Enter();
    5.  
    6.     //enable the nav
    7.     _nav.enabled = true;
    8.  
    9.     //get target
    10.     _target = _owner.Target.transform;
    11.  
    12.     //get the offset
    13.     _offset.x = (Random.Range(-1.0f, 1.0f) < 0.0f ? -_owner.ArmLength : _owner.ArmLength);
    14.     _offset.z = (Random.Range(-1.0f, 1.0f) < 0.0f ? -1.0f : 1.0f);
    15. }
    16.  
    Execute:
    Code (CSharp):
    1.  
    2. public override void Execute()
    3. {
    4.     base.Execute();
    5.  
    6.      //use the nav mesh to guide towards player
    7.     if ((_transform.position - (_target.position + _offset)).sqrMagnitude > (_manual_move_zone * _manual_move_zone))
    8.     {
    9.          //we want to move with the nav mesh agent so make sure it is enabled
    10.          //(this check is required incase we come from moving manually to this)
    11.          if (_nav.enabled == false) _nav.enabled = true;
    12.  
    13.         //keep updating the destination
    14.         _nav.SetDestination(_target.position + _offset);
    15.  
    16.         //if they are in arms length go back to decision make to...make a decision on what to do.
    17.         if (_gm.Players.PlayersInArmLength(_transform.position, _owner.Direction, _owner.ArmLength, _owner.ZReach).Count > 0)
    18.         {
    19.             //go to decision make to see what to do
    20.             _sm.SwapState("DecisionMake");
    21.         }
    22.     }
    23.     else
    24.     {
    25.         //we want to move manually so make sure the nav mesh agent is disabled
    26.         if (_nav.enabled) _nav.enabled = false;
    27.  
    28.         //move manually
    29.         Vector3 target = (_target.position + _offset);
    30.  
    31.         //store the y value (so we keep a constant y position in the transform)
    32.         float y = _transform.position.y;
    33.  
    34.         //move to position
    35.         Vector3 pos = Vector3.MoveTowards(_transform.position, target, _owner.Speed * Time.deltaTime);
    36.  
    37.         //set the original y value
    38.         pos.y = y;
    39.         _transform.position = pos;
    40.  
    41.         //if we are in the pposition fo to decision making state
    42.         if ((_transform.position - target).sqrMagnitude <= 0.2f)
    43.         {
    44.              _sm.SwapState("DecisionMake");
    45.         }
    46.     }
    47.            
    48.     //make sure we are facing target
    49.     _owner.FaceTarget();
    50. }
    51.  
    Exit:
    Code (CSharp):
    1.  
    2. public override void Exit()
    3. {
    4.     base.Exit();
    5.  
    6.     //disable the nav
    7.     _nav.enabled = false;
    8. }
    9.  

    Any ideas as to why this may be happening?

    Thanks,
    Nick
     
  2. NickXDStudios

    NickXDStudios

    Joined:
    Jul 8, 2014
    Posts:
    5
    Okay I seem to have fixed it, however it seems a really weird fix....

    Turns out when the NavMeshAgent is enabled it ignores the box collider component the rigid body uses to prevent from falling through the ground and uses its own cylinder object. And when it is disabled it reverts back to using the box collider....

    However, when I created the NavMeshAgent I thought about this and made them perfectly aligned and no matter how much I kept the y coordinate constant it still jumped up a little off the ground when the NavMeshAgent was enabled and then went back on the ground plane perfectly when it wasn't. Although this caused the bug as when flicking between enabled and disabled the game object collider would go through the ground a little bit and fall through the floor....

    Why is the NavMeshAgent making the object appear off the ground a tiny bit? Even the NavMesh is perfectly flat on the ground plane....

    But anyway if you're having this problem I fixed it by offsetting the NavMeshAgent base offset a tiny bit higher than the box collider so it would appear to be on the floor when flicking between the enable/disable states.
     
    pythonhugs likes this.
  3. chaseholton

    chaseholton

    Joined:
    Dec 17, 2012
    Posts:
    78
    I know this is old, but there was something wacky happening to my AI when being hit and disabling / enabling the NavMeshAgent... I hope this is the simple solution I’ve been seeking! Haha
     
  4. Hammer2k7

    Hammer2k7

    Joined:
    Dec 1, 2020
    Posts:
    1
    Experiencing the same thing now
     
  5. Buezinho

    Buezinho

    Joined:
    Mar 27, 2021
    Posts:
    1
  6. MarkSharpe

    MarkSharpe

    Joined:
    Feb 3, 2021
    Posts:
    27
    My guess is you guys better start looking into behavior trees