NavmeshAgent rotating and moving with root motion animations
Navmesh coupled with and animations gives me a headache for the last 2 weeks. I am struggling to create good looking animations and create a better experience for the player. Already checked unity docs : https://docs.unity3d.com/Manual/nav-CouplingAnimationAndNavigation.html, but unfortunately this does not give the expected result. https://gifyu.com/image/lNSL here is a gif that shows the problem. He is moving while also rotating and does not look natural. I seached the web to find different ways of setting the animator based on the agent.desiredVelocity
, difference vector agent.nextPosition - transform.position
etc. The problem with all these approaches is that the agent will end up rotating from the agent/code(via : transform.Rotate()
or a smooth Lerp of quaternions using Quaternion.LookRotation()
etc) and update position(move) at the same time.
I was curios to see how the AIThirdPersonController from Standard Assets is implemented. They are using a 2d blend tree with angle and forward as parameters, and pass agent.desiredVelocity
to ThirdPersonCharacter.Move()
function. Fair enough. The problem is that they are rotating the character from code more than with the root motion. As a consequence the rotation is quite fast and not very human-like. The code does more than the animation really. In my opinion animation should go by itself and be helped by a code rotation.
(you can checkout the code here: https://pastebin.com/70RJxhs6 (thid person.cs) (is modified to show the ApplyExtrRotation(). without that function there will be no rotation in the character))
What I have tried so far is to stop the agent when he has to perform a rotation. let the rootmotion handle it and the reactivate the agent, then move.
using UnityEngine;
using UnityEngine.AI;
public class AnimateAI : MonoBehaviour
{
[SerializeField] private float angleAccuracy = 1f;
NavMeshAgent agent;
Animator animator;
Vector3 lastDirection;
float angle;
float lastAngle;
private bool rotating = false;
// Start is called before the first frame update
void Start()
{
animator = GetComponent<Animator>();
agent = GetComponent<NavMeshAgent>();
agent.updatePosition = false;
agent.updateRotation = false;
}
void Move(Vector3 direction)
{
if (agent.hasPath == false)
return;
angle = Vector3.Angle(transform.forward, direction) * Mathf.Sign(Vector3.Dot(transform.right, direction));
//angle = Mathf.Atan(direction.x / direction.z) * Mathf.Rad2Deg; (returns a different angle and has an error of 10 degrees
if (Mathf.Abs(lastAngle) < angleAccuracy && angle != 0)
{
animator.SetFloat("Rotation",angle / 90);
}
animator.SetFloat("Velocity",direction.magnitude / agent.speed);
rotating = (Mathf.Abs(angle) > angleAccuracy);
lastAngle = angle;
}
// Update is called once per frame
void Update()
{
if (agent.isStopped == false)
lastDirection = agent.desiredVelocity;
Move(lastDirection);
}
private void OnAnimatorMove()
{
transform.rotation = animator.rootRotation;
if (rotating)
{
agent.isStopped = true;
transform.position = animator.rootPosition;
agent.nextPosition = transform.position;
Debug.Log("now rotating");
}
else
{
Debug.Log("now moving");
agent.isStopped = false;
transform.position = agent.nextPosition;
}
}
}
aniamator look : https://ibb.co/3T8yhTj start walk should handle the way the characters rotate and then transition automatically in the simple walk blend tree. start walking : https://ibb.co/7bpsb47 (2 means 180 turn, 1 means 90 turn, 1.5 = 135 turn,0 = 0 turn) https://gfycat.com/impeccabledisfiguredelkhound how it looks in the scene.
The animations put in the start walk blend tree prepare the cycle for walking. https://gfycat.com/meagerboldbushbaby How can I get the most out of the animations? (they have for 130 also) (animations from MovementAnimsetPro). Should I hard code angle values to turn from code? How do you guys do you own animators for agents?
Your answer
Follow this Question
Related Questions
Rigidbodies stopping Root Motion of animations 0 Answers
My animation is causing rotation errors 0 Answers
Making your ai attack then return to the navmesh when player leaves trigger 0 Answers
Sprite rotation clip & ending position 0 Answers
How to set animations for a top down shooter? How to change the animations by the player rotation? 0 Answers