RVO using Recast Graph and Mecanim

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? :slight_smile:

Thanks!

Nobody has an answer? :disappointed:

Hi Henk,

In your post you don’t explain the problem you are facing, you are simply stating “it doesn’t work” and then added the code :slight_smile: Basically to answer you one has to create a repro project, drop in your script and hope to have created something similar to your setup … Not gonna happen :smile: I suggest you to clarify the problem you are facing, maybe also adding a 30 seconds video to show what’s happening, so that who reads your post can get the clear picture of your request for help :wink:

-Pino

1 Like

You are absolutely right! What I mean is that I can’t get root motion to work so that the characters do not ‘slide’ across the floor :slight_smile:

I received an email from Aron with some instructions so I will try this out today.

But is is what it looks like now:

This is the best I could get it but the calculation of the angle is turned off so the angle is always 0.
The sliding gets much worse when turning on the angle calculation in the locomotion script.

UPDATE:
I’ve created a new example video where also the angle is calculated: