- Home /
How do you update NavMesh rotation after stopping distance is reached?
I can't seem to figure this out. I have the stopping distance set to 1.5 so my AI stops, but when he does he stops rotating towards the target allowing the player to closely sneak behind the enemy without him rotating to the player. This makes it easy for the player to do this with large groups of enemies exploiting the game, due to a ranking system with XP and emblems.
This is written in JS.
I know I can use NavComponent.updateRotation = true but that doesn't seem to work. I tried a custom rotation, look at function, but that doesn't seem to work either.
var dir = target.position - transform.position;
dir.y = 0; // keep only the horizontal direction
var rotation = Quaternion.LookRotation(dir);
transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * damping);
This is only called when the player is within the attack distance of about 3. How can I get the enemy to always rotate towards the player/target?
I would post the code here but I'm not aloud to. There is nothing wrong with the code itself it's just a working rotate towards function I'm looking for that works with NavMesh.
I'm also using a rigidbody on the enemy to give him gravity. Could this be causing an issue? If anyone could point me in the right direction it would be greatly appreciated. I'm only here as a last resort because I can't seem to get it working myself.
Thanks in advanced.
Of course after I post this I find a solution and of course it was a stupid one. The damping speed wasn't set high enough..
Answer by Escwald · May 20, 2014 at 11:13 AM
I had the exact same issue and solved it by rotating the object with the agent if target was in melee range. Below is a snippet of my code. It is written in C#, but should be easy to adapt into JavaScript and similar needs.
public float meleeRange = 3f;
public float rotationSpeed = 10f;
void Update () {
Transform target = null;
// Code here that decides what target is
MoveTowards(target);
if (IsInMeleeRangeOf(target)) {
RotateTowards(target);
}
}
private bool IsInMeleeRangeOf (Transform target) {
float distance = Vector3.Distance(transform.position, target.position);
return distance < meleeRange;
}
private void MoveTowards (Transform target) {
agent.SetDestination(target.position);
}
private void RotateTowards (Transform target) {
Vector3 direction = (target.position - transform.position).normalized;
Quaternion lookRotation = Quaternion.LookRotation(direction);
transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * rotationSpeed);
}
To add on to this, if you want to make it so the nav agent only rotates about the y axis, you can change the RotateTowards function like so:
private void RotateTowards(Transform target)
{
Vector3 direction = (target.position - transform.position).normalized;
Quaternion lookRotation = Quaternion.LookRotation(new Vector3(direction.x, 0, direction.z)); // flattens the vector3
transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * rotationSpeed);
}
If you want more direct control over the speed with which the object rotates, you can use Quaternion.RotateTowards within the custom RotateTowards method. It allows you to set the maximum number of degrees per second to rotate. So ins$$anonymous$$d of setting transform.rotation using Quaternion.Slerp, you could use the following:
transform.rotation = Quaternion.RotateTowards(transform.rotation, lookRotation, Time.deltaTime * rotationSpeed);
You do, however, lose the smoothing effect of Slerp, so there's a tradeoff.
Note: I've only tested this when rotating around the Y axis alone, though I believe it should work for other rotations, as well.
Answer by RavenOfCode · Jan 17, 2016 at 03:38 PM
Update the NavMeshAgents rotation variable:
nMA is my NavMeshAgent.
nMA.updateRotation = true;
updateRotation
is the important thing! Note that if you want to manually update rotation, set this to false
.
API reference: https://docs.unity3d.com/ScriptReference/Nav$$anonymous$$eshAgent-updateRotation.html
The updateRotation flag only matters when the Nav$$anonymous$$esh Agent has not reached its destination. The problem that the OP was facing was that the Nav$$anonymous$$esh Agent had reached its destination (was within the stopping distance) and therefore stopped rotating to face it. In that case, updateRotation was still set to true, but it was not rotating because it was considered to be at the destination.
Answer by carboro · Dec 01, 2021 at 10:07 AM
if you do same animation set the code in fixed Update its battery : )
Your answer

Follow this Question
Related Questions
Look at around one axis in local space 1 Answer
LookAt() rotation difference from rotating the object(position does not change) 1 Answer
Rotation using Unity2D 3 Answers
LookAt inaccurate rotation issue (javascript) 1 Answer
Lock rotation axis? 4 Answers