Driver NavMeshAgent & Enter Car Animation


Today I added NavMeshAgent to the driver which makes him run to the car. I am also refactoring to tidy up the code and separating Car and Driver into separate scripts. The Driver can now have different states which I keep track of with an enum:

public enum State { Outside, GoingToCar, EnteringCar, ExitingCar, InCar }
public State state = State.Outside;

I added the NavMeshAgent component to the driver and made the racetrack/environment (which is single mesh at this point) into a static object for the baked NavMesh. That's pretty much all that's needed to get core mechanics to work for the driver to be able to move across the track and surrounding environment. The only thing that's missing is the run animation:


I also created a walk animation with the same number of key frames. Basically, the main difference is that the character's feet are never in the air simultaneously:


With those two animation (and a somewhat static idle animation where the character basically only breathes) I but together a BlendTree in Unity:


The NavMeshAgent has the speed set to 3.5 so in my code for the driver I set the Movement animator variable in the Update() method by dividing the Speed value by 3.5:

_animator.SetFloat("Movement", _navMeshAgent.velocity.magnitude / 3.5f);

The car gameobject has a child transform that designates the position next to the driver's door and the script uses that position as a destination for the NavMeshAgent:

_navMeshAgent.SetDestination(car.entryExitPosition.position);

When the driver reaches the destination it triggers an animation on the Driver to open the car door, enter the car, and then close the car door. This is how I detect in the driver script that the NavMeshAgent has reached the destination:

void Update() 
{
    if (state == State.GoingToCar)
            {
                if (!_navMeshAgent.enabled)
                    _navMeshAgent.enabled = true;
                float _dist = _navMeshAgent.remainingDistance;
                if (_dist != Mathf.Infinity && _navMeshAgent.pathStatus == NavMeshPathStatus.PathComplete && _navMeshAgent.remainingDistance == 0)
                {
                    if (Vector3.Distance(transform.position, car.entryExitPosition.position) < 0.05f)
                    {
                        EnterCar();
                    }
                }
                _animator.SetFloat("Movement", _navMeshAgent.velocity.magnitude / 3.5f);
            }
}

The EnterCar() method that is called simply triggers the EnterCar animation in the driver's Animator graph:

public void EnterCar()
    {
        _navMeshAgent.isStopped = true;
        _navMeshAgent.enabled = false;
        transform.rotation = car.entryExitPosition.rotation;
        _animator.SetTrigger("EnterCar");
        state = State.EnteringCar;
    }

Finally, the car door itself need to open and then close at certain points and it needs to be a fairly close match to the driver's arm movements of opening and closing the door. I'm not too bothered with Inverse Kinematic perfection because remember, this animation will be viewed from a birds eye isometric top down view:

I configured two "Events" in the Driver animation for OpenEnterSitClose and the two events are triggering methods (functions) of the Car gameobject name OpenDoor() and CloseDoor(). This way I can ensure that the animations of the driver and the car door are synced "good enough" to look nice from a distance:


The methods in the Driver script are super simple - they just call an equivalent method in the Car script:

public void OpenDoor()
    {
        car.OpenDoor();
    }
public void CloseDoor()
    {
        car.CloseDoor();
    }

...and similarly the methods in the Car scripts for opening and closing the doors are super simple too:

public void OpenDoor()
    {
        _animationDriverDoor.clip = _animationDriverDoor.GetClip("OpenDoor");
        _animationDriverDoor.Play();
    }
public void CloseDoor()
    {
        _animationDriverDoor.clip = _animationDriverDoor.GetClip("CloseDoor");
        _animationDriverDoor.Play();
    }

The car door gameobject has an Animation component added to it and I created two animations using the built in Unity3D animation feature. The OpenDoor animation rotates the door gameObject by 50 degrees around the Y (up) axis and the CloseDoor animation rotates the door gameObject back by 50 degrees. The pivot point of the door gameObject has been set to where the hinges are to make sure the door rotates appropriately and not around it's center.

So then, that's it for today's post. Hopefully it gives some insight to the development process and maybe even some tips if you want to make something similar!

Stay updated and please spread the word of this game and share this page :)

Files

That's-Racing-Wallpaper.png 1 MB
Jun 07, 2018

Leave a comment

Log in with itch.io to leave a comment.