How to move a character with a NavMesh & raycasts! (Unity/C#)

Let’s see how to move a Unity 3D character with the mouse 🙂

This article is also available on Medium.

This tutorial is available either in video format or in text format — see below 🙂

Project Overview

Ok so: let’s say I have this basic Unity project with a 3D character, a ground plane and some walls.

Now, I want to add some movement to this character so that, whenever I click somewhere on the floor, my character automatically walks towards it and avoids the walls if need be.

To do this, I’m going to rely on two nice Unity tools: the built-in navigation system and the raycasts.

Using Unity’s Navigation System

Let’s start with the navigation setup.

The idea of the Unity navigation system is to define a navigation mesh and agents to walk on it with a pre-built AI for pathfinding. Basically, the nav mesh is going to re-map the floors in your scene as a really thin grid of cells so that the pathfinding algorithm of the nav agent, based on the famous A-Star, can find the best path to the target point. This re-mapping can also take into account various obstacles that cut “holes” in it and prevent the agent from going near those areas.

So to begin with, I need to setup my scene so that the engine knows what I consider to be the ground, the obstacles and the moving agent. Let’s open the “AI > Navigation” window and properly configure the objects in our scene.

First, I’ll select my ground plane and mark it as a “Navigation Static” object. Then, I’ll bake my nav mesh.

From that point on, the ground is a walkable area for all my nav agents and I can actually check this out by enabling the Nav Mesh display on my object.

The problem is that, for now, the walls aren’t real obstacles. The agents still consider these areas are walkable. To fix this, I need to add a Nav Mesh Obstacle component onto those wall game objects and make sure to toggle on the “Carve” option so that they cut a hole in the nav mesh.

Finally, I can add a Nav Mesh Agent component to my character.

Adding the C# scripts

Now, to actually make my character move, I need to add some C# logic on it to use the nav mesh agent and update its destination point based on the position where we click with the mouse.

So let’s create a new C# script called MoveAgent.cs and get a reference to our Nav Mesh Agent. We can add a [RequireComponent] attribute to insure that any object with this MoveAgent script also has a NavMeshAgent component on it:

This means I can assume there is a NavMeshAgent on my character game object and I can use GetComponent() to fill in my reference during the Awake(). Also, I’m going to need a reference to my main camera and it’s better to cache it for performance:

Then, in my Update(), I’ll check if I’m pressing the left-mouse button and, if I am, I’ll use my main camera reference to compute a ray from the camera to the cursor position. Finally, I can use this ray to do a raycast check with Unity’s built-in Physics.Raycast() function and output the result in a RaycastHit variable. Of course, you should make sure that your ray is long enough to reach your ground object 😉

And to optimise your code, you can assign your floor object to a specific physics layer: this way, the raycast will be limited to just this layer and the engine won’t have to do as many collision checks. Unity layers are defined using bitmasks so, for example, if your ground layer is the number 6, you’ll have to set the variable to be 1 left-shifted by 6.

Don’t forget to assign your ground object to the layer 🙂

Finally, all that’s left to do in our C# is assign the raycast hit point as the nav mesh agent destination – and our character will automatically start moving towards it!

Of course, for more complex characters like mine, with animations and all, you’ll need some additional C# code to change the animation state, for example, but all in all, with just a dozen lines of code, we’ve successfully made a simple player controller that can walk on the ground, go around the walls and reach whichever position we set with our mouse!

Conclusion

I hope you enjoyed this short tutorial – make sure to like and share it if you did! And of course, feel free to drop a comment with your idea for a future Unity tutorial 😉

As always, thanks a lot for reading and stay tuned for more articles on coding and games!

Leave a Reply

Your email address will not be published.