Hi, This question is asked several times now but I can’t get it to work.
First I used Unity’s NavMeshAgents in combination with Mecanim to control my NPC’s. The setup I used is the same as an ‘old’ Unity example project called Stealth (locomotion of the enemy robots).
Because Unity’s NavMesh doesn’t do local avoidance very well I bought Pathfinding Pro and I’m trying to rewrite parts of the code to make it work.
My locomotion script looked like this:
public class CharacterLocomotion : MonoBehaviour
{
/// <summary>
/// Set Active to false if locomotion is not used. This is just for optimizing performance.
/// </summary>
public bool Active { get; set; }
private float _deadZone = 4f;
private Animator _anim;
private AnimatorSetup _animSetup;
private NavMeshAgent _nav;
protected void Start()
{
_nav = GetComponent<NavMeshAgent>();
_anim = GetComponent<Animator>();
_nav.updateRotation = false;
_animSetup = new AnimatorSetup(_anim);
_deadZone *= Mathf.Deg2Rad;
}
protected void Update()
{
if (!Active)
return;
NavAnimSetup();
}
public void OnAnimatorMove()
{
if (_anim == null)
return;
_nav.velocity = _anim.deltaPosition / Time.deltaTime;
transform.rotation = _anim.rootRotation;
}
private void NavAnimSetup()
{
var speed = Vector3.Project(_nav.desiredVelocity, transform.forward).magnitude;
var angle = FindAngle(transform.forward, _nav.desiredVelocity, transform.up);
//prevent 'snake' behavior (overcompensation)
if (Mathf.Abs(angle) < _deadZone)
{
transform.LookAt(transform.position + _nav.desiredVelocity);
angle = 0f;
}
_animSetup.Setup(speed, angle);
}
private static float FindAngle(Vector3 fromVector, Vector3 toVector, Vector3 upVector)
{
if (toVector == Vector3.zero)
return 0f;
var angle = Vector3.Angle(fromVector, toVector);
var normal = Vector3.Cross(fromVector, toVector);
angle *= Mathf.Sign(Vector3.Dot(normal, upVector));
angle *= Mathf.Deg2Rad;
return angle;
}
}
The AnimatorSetup class Looks like this:
public class AnimatorSetup
{
private readonly Animator _anim;
public float AngleResponseTime = 0.7f;
public float AngularSpeedDampTime = 0.8f;
public float SpeedDampTime = 0.3f;
private readonly int _speedHash;
private readonly int _angularSpeedHash;
public AnimatorSetup(Animator animator)
{
_anim = animator;
_speedHash = Animator.StringToHash(AnimParams.Speed);
_angularSpeedHash = Animator.StringToHash(AnimParams.AngularSpeed);
}
public void Setup(float speed, float angle)
{
var angularSpeed = angle/AngleResponseTime;
_anim.SetFloat(_speedHash, speed, SpeedDampTime, Time.deltaTime);
_anim.SetFloat(_angularSpeedHash, angularSpeed, AngularSpeedDampTime, Time.deltaTime);
}
}
I have tried different thinks to integrate A* Pathfinding Pro but without the desired outcome.
(I’m working with the latest beta version because I also need the NPC’s to avoid the First Person Player)
Does anyone have a good working solutions for this and wants to share it?
Thanks!