Search Unity

How do I update the rotation of a NavMeshAgent?

Discussion in 'Navigation' started by kritoa, Jul 9, 2019.

  1. kritoa

    kritoa

    Joined:
    Apr 21, 2017
    Posts:
    60
    I have a creature which has constraints on the way it moves and rotates, so I have a custom movement script which uses the NavMeshAgent indirectly:

    Code (CSharp):
    1. void Start(){
    2.     NavMeshAgent agent = GetComponent<NavMeshAgent>();
    3.     agent.updatePosition = false;
    4.     ...
    5. }
    6.  
    7. void Update(){
    8.     Vector3 targetVel = (agent.nextPosition = transform.position)/Time.deltaTime;
    9.     DoCustomMovement(targetVel );
    10.     agent.nextPosition = transform.position;
    11. }
    This successfully implements a custom movement driven by the navMeshAgent, but how do I do custom rotation? I see there is a NavMeshAgent.updateRotation that I can also set to false, but there is no NavMeshAgent.nextRotation() to get to use in my custom rotation code, or to set (to let the NavMeshAgent know where my creature is facing).

    Or does the NavMeshAgent assume that the creature is rotated towards the direction of travel (i.e. it is always moving forwards, never strafing?).
     
    Snake-M3 likes this.
  2. Yandalf

    Yandalf

    Joined:
    Feb 11, 2014
    Posts:
    491
    I think you're right and that the standard navmeshagent behaviour assumes you always move in the direction of the forwards vector, so you'll be always rotated towards nextPosition.
    It's my main gripe with the navigation solution in Unity, there's no real way to change the basic movement behaviour.
     
  3. kritoa

    kritoa

    Joined:
    Apr 21, 2017
    Posts:
    60
    I guess I'm still confused about how to effect a rotation if the agent is not moving. If the agent is moving in an arc (where the rotation speed is bounded by the agent's max rotation speed but is otherwise walking forwards) I'll be fine, but in the case where the agent is stationary I don't know where to get the "nextRotation" from. (e.g. if the agent is pressed against a wall and is told to walk the other direction it will normally remain stationary while it rotates around - but if I want to take care of the rotation myself I have apparently no way of getting that information,

    I suppose I could have the NavMeshAgent actually control (updateRotation = true) an empty GameObject and steal the information from that transform node. Seems gross.

    I guess since the default NavMeshAgent doesn't support any kind of sidestepping anyway, perhaps I just need to set the NavMeshAgent's angularspeed to some really, really high number and then just deal with my character's facing direction completely on my own.
     
  4. InsaneDuane

    InsaneDuane

    Joined:
    Nov 1, 2019
    Posts:
    9
    Try this:
    Code (CSharp):
    1.     void FaceTarget()
    2.     {
    3.         var turnTowardNavSteeringTarget = navMeshAgent.steeringTarget;
    4.      
    5.         Vector3 direction = (turnTowardNavSteeringTarget - transform.position).normalized;
    6.         Quaternion lookRotation = Quaternion.LookRotation(new Vector3(direction.x, 0, direction.z));
    7.         transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * 5);
    8.     }
    I've been working on NPC movement and I dislike foot-slide. RootMotion set to true fixes this issue but it didn't work well with the NavMeshAgent. The NavMeshAgent doesn't turn unless the speed is set to 0.05 or higher, which can cause negligible foot-slide. I found the "NavMeshAgent.steeringTarget" return value which doesn't give you it's end destination but instead gives back it's immediate destination while navigating towards it's end destination. All you have to do now is set your characters rotation to match the NavMeshAgent.steeringTarget rotation.
     
  5. kalotarasagar928

    kalotarasagar928

    Joined:
    Sep 12, 2022
    Posts:
    1
    promblem solved !! THANKS FOR CODE!
     
    Hcq7 likes this.
  6. ILLIDEN33

    ILLIDEN33

    Joined:
    Aug 21, 2023
    Posts:
    1
    will you please change it for 2D top down game?
     
  7. unity_EIIGOG40DY7XfA

    unity_EIIGOG40DY7XfA

    Joined:
    Oct 13, 2021
    Posts:
    1
    Code (CSharp):
    1. _transform.right = _agent.steeringTarget - _transform.position