Search Unity

Using Cinemachine to Follow Character using NavMeshAgent

Discussion in 'Editor & General Support' started by chainsawpenguin, Nov 22, 2018.

  1. chainsawpenguin

    chainsawpenguin

    Joined:
    Sep 28, 2014
    Posts:
    107
    Good evening, team!

    I'm trying to use the Cinemachine virtual camera to follow my character, while also navigating the character around on the NavMesh using a NavMeshAgent.

    I can get this working using a Top-Down view just fine, and I've included the code at the bottom. What I can't do is put the camera BEHIND the player to follow him around. If I do that, the orientation of what "forward" means keeps changing, because while the model rotates to face the direction of movement, the NavMeshAgent does not. This makes some sense; the NavMeshAgent just needs to get from point A to point B, and that problem does not involve facing at all.

    However, the value of Vector3.forward does not change when the model rotates, so it looks like it's tied to the NavMeshAgent, but I can't figure out how to get the NavMeshAgent to "face" the direction of rotation, since the NavMeshAgent doesn't seem to care about facing...

    The consequence of this is that when you turn the character to the left by pressing left on the horizontal input, the player turns and moves to its left, but the camera then swings around behind him, and your instinct is to press up to keep moving in the same direction, but that now causes the player to move to its right, and pressing down causes the player to move to its left, and pressing right causes the character to reverse direction by 180 degrees, all of which is really disorienting.

    Anyway, my code is below. If you put a Cinemachine camera looking down at the player, following and looking at a child object of the player, with a Binding Mode of "World Space", you'll see that this works just fine, but you're sort of in "Pac-Man" mode: pressing up moves you vertically on the screen, pressing left moves you left on the screen, etc.

    Finally, and just pre-emptively: I'm NOT trying to use a Character Controller. This question has been asked multiple times over the last few years, and the discussions generally fall apart when the first person asks "Why don't you just use a Character Controller?" so let me try to head that off at the pass: just assume that that is not an option. Let's try to solve this problem, so that we can have a good, clear answer for this very particular situation!

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.AI;
    [RequireComponent(typeof(NavMeshAgent))]
    public class PlayerControl_NavMesh : MonoBehaviour {
    private Vector3 myGoal;
    public NavMeshAgent myAgent;
    public Animator myAnimator;
    void Start()
    {
    Cursor.visible = false;
    myGoal = transform.position;
    myAgent = GetComponent<NavMeshAgent>();
    myAnimator = GetComponent<Animator>();
    }
    void Update ()
    {
    myGoal = transform.position
    + Vector3.forward * Input.GetAxis("Vertical")
    + Vector3.right * Input.GetAxis("Horizontal");
    myAgent.destination = myGoal;
    myAnimator.SetFloat("mySpeed", myAgent.velocity.magnitude);
    }
    }