NPC Follow Player in Unity

Non-Player Characters or NPCs are the characters that are not controlled by a human player and instead are controlled by the scripts or the AI.

The most common task that NPCs have to do, is to follow or chase the Player.

In this tutorial, I will be showing how to make an NPC that follows the player in Unity.

Step 1: Create a Player Controller

We will create a simple Player Controller, so we can walk around and test the NPC:

  • Create new GameObject (GameObject -> Create Empty) and name it “Player”
  • Create new Capsule (GameObject -> 3D Object -> Capsule), move it inside Player Object and change its position to (0, 1, 0)
  • Remove the Capsule Collider component from a Capsule
  • Move the Main Camera inside Player Object and change its position to (0, 1.64, 0)

Create a new script, name it SC_CharacterController then paste the code below inside it:

SC_CharacterController.cs

using UnityEngine;

[RequireComponent(typeof(CharacterController))]

public class SC_CharacterController : MonoBehaviour
{
    public float speed = 7.5f;
    public float jumpSpeed = 8.0f;
    public float gravity = 20.0f;
    public Camera playerCamera;
    public float lookSpeed = 2.0f;
    public float lookXLimit = 45.0f;

    CharacterController characterController;
    Vector3 moveDirection = Vector3.zero;
    Vector2 rotation = Vector2.zero;

    [HideInInspector]
    public bool canMove = true;

    void Start()
    {
        characterController = GetComponent<CharacterController>();
        rotation.y = transform.eulerAngles.y;
    }

    void Update()
    {
        if (characterController.isGrounded)
        {
            // We are grounded, so recalculate move direction based on axes
            Vector3 forward = transform.TransformDirection(Vector3.forward);
            Vector3 right = transform.TransformDirection(Vector3.right);
            float curSpeedX = speed * Input.GetAxis("Vertical");
            float curSpeedY = speed * Input.GetAxis("Horizontal");
            moveDirection = (forward * curSpeedX) + (right * curSpeedY);

            if (Input.GetButton("Jump"))
            {
                moveDirection.y = jumpSpeed;
            }
        }

        // Apply gravity. Gravity is multiplied by deltaTime twice (once here, and once below
        // when the moveDirection is multiplied by deltaTime). This is because gravity should be applied
        // as an acceleration (ms^-2)
        moveDirection.y -= gravity * Time.deltaTime;

        // Move the controller
        characterController.Move(moveDirection * Time.deltaTime);

        // Player and Camera rotation
        if (canMove)
        {
            rotation.y += Input.GetAxis("Mouse X") * lookSpeed;
            rotation.x += -Input.GetAxis("Mouse Y") * lookSpeed;
            rotation.x = Mathf.Clamp(rotation.x, -lookXLimit, lookXLimit);
            playerCamera.transform.localRotation = Quaternion.Euler(rotation.x, 0, 0);
            transform.eulerAngles = new Vector2(0, rotation.y);
        }
    }
}
  • Attach the SC_CharacterController script to Player Object and assign a child Main Camera to a Player Camera variable
  • You will notice it automatically added another component called Character Controller, change its center position to (0, 1, 0)

Step 2: Create the NPC

To create an NPC, follow the steps below:

  • Create a new GameObject and name it “NPC
  • Create a new Capsule, move it inside NPC Object and change its position to (0, 1, 0)
  • Create new Material and name it “npc_material”
  • Change the color of npc_material to red
  • Assign npc_material to Capsule inside NPC Object (this is just so we can distinguish NPC from the Player)

Before continuing, we need to bake the NavMesh in our Scene.

NavMesh stands for “Navigation Mesh” and is used in pathfinding to allow NPCs to navigate the level without bumping into the obstacles.

To bake the NavMesh, follow the steps below:

  • Mark every static Object in the Scene as Navigation Static
  • Go to Navigation Window (Window -> AI -> Navigation), select Bake Tab then click Bake

After the NavMesh is baked, it should look something like this:

Unity 3D NavMesh Bake

Now we can move to the programming of the NPC movement:

  • Attach NavMesh Agent component to NPC Object
  • Create a new script and name it SC_NPCFollow
  • Attach SC_NPCFollow script to NPC Object
  • Open the SC_NPCFollow script

First, we begin by adding a UnityEngine.AI namespace at the beginning of the script:

using UnityEngine.AI;

Then we define the necessary variables:

    //Transform that NPC has to follow
    public Transform transformToFollow;
    //NavMesh Agent variable
    NavMeshAgent agent;

In the void Start() we begin by getting the NavMesh Agent component attached to this Object:

    // Start is called before the first frame update
    void Start()
    {
        agent = GetComponent<NavMeshAgent>();
    }

And finally, in the void Update() we instruct the NavMesh Agent to follow the Player:

    // Update is called once per frame
    void Update()
    {
        //Follow the player
        agent.destination = transformToFollow.position;
    }

Here is the final SC_NPCFollow.cs script:

using UnityEngine;
using UnityEngine.AI;

public class SC_NPCFollow : MonoBehaviour
{
    //Transform that NPC has to follow
    public Transform transformToFollow;
    //NavMesh Agent variable
    NavMeshAgent agent;

    // Start is called before the first frame update
    void Start()
    {
        agent = GetComponent<NavMeshAgent>();
    }

    // Update is called once per frame
    void Update()
    {
        //Follow the player
        agent.destination = transformToFollow.position;
    }
}

Fixing some issues:

Issue 1: After pressing Play, the NPC capsule hovers above the ground:

Solution: Change the Base Offset variable in NavMesh Agent to a negative value (in my case it’s -0.08)

Issue 2: The NPC comes too close when following the Player:

Solution: Change Stopping Distance in NavMesh Agent to a higher value (in my case I set it to 5)

The NPC is now ready, let’s test it:

Everything works as expected, the NPC now follows the Player and stops at a set distance.

Leave a Reply

Your email address will not be published. Required fields are marked *