Thursday 10 November 2022

NavMesh 01

The NavMesh, is a 3D mesh that facilitates the movement of game objects which have the 'Nav Mesh Agent' component attached to them. 

I watched a Youtube video of a very similar example, however generally I like to start from scratch rather than a pre or half baked solution.

Let's start by Creating a brand new Unity Project from the Unity hub

Once you hit 'Create project' depending on your computer, this may be a great time to either grab a coffee or a nap.... After anywhere from 2 to 15 minutes your Empty Unity Project should be open.

Before we get started let's make sure that you have the Navigation Panel open in your project.
go to Window  -> AI ->Navigation

You can snap it anywhere within your project, I for me it just makes sense to tab it with my Inspector.

Optionally you can add the ProGrids package, via the package manager, keep in mind that currently ProGrids is an experimental package and has to be added by Name.

Some of the components that you are going to need do not ship standard with Unity, you have to explicitly add the package by name, because at this time they are 'Experimental', but you're a badass so go head and experiment. 

Open Window-> Package Manager.


With that done we can finally get started. 

Add a 'Plane' to your main hierarchy,

Next, let's create an 'Empty' GameObject in the Hierarchy and add a NavMeshSurface Component to it


Next, in your Assets folder add a 'Scripts' folder and in that freshly created 'Scripts' folder create a PlayerController.cs script.



You'll have to rename it from the default 'NewBehaviourScript.cs' name. Open your script, in your preferred IDE, personally I use MS Code. paste in the following code

//added UnityEngine namespaces
using UnityEngine;
using UnityEngine.AI;
public class PlayerController : MonoBehaviour
{
    //reference of the camera to know what the user clicked on
    public Camera Camera;

    //reference to the thing that will move
    public NavMeshAgent Agent;

    //Create an enum for mouse buttons
    enum MouseButton{ Left = 0, Right = 1, Scroll = 3 }

    // Update is called once per frame
    void Update()
    {
        //check if the user left clicked on something
        if(Input.GetMouseButtonDown((int)MouseButton.Left)){
            //what did the user click on
            RaycastHit hit;
           
            //where did the user click on the screen
            var pos = Input.mousePosition;

            //where from the camera's perspective did the user click
            var ray = Camera.ScreenPointToRay(pos);

            //did the user click on an object
            if(Physics.Raycast(ray, out hit))
                //send the agent to the point the user clicked on
                Agent.SetDestination(hit.point);
        }
    }
}

The above code figures out what did the user click on and tells the agent to go there.

Now we are going to add our PlayerController.cs Script to an 'Empty' game object in our Hierarchy, right click in the Hierarchy and select the 'Create Empty' option.


Once you have created your Empty game Object make sure to add our new Player Controller Script to the 'PlayerController' Game Object. 

While we are add it let's add the reference to our Main Camera, click the little circle next to our camera input and select the main Camera.


with our camera reference added, it seems that we now need to create an agent; for simplicity sake let's add a Sphere to our hierarchy and name it Player. Select your Player game object and hit the 'F' key on your keyboard, this will bring it into focus, make sure that you position it above your plane.


Keep in mind that your position values may be different from mine, all you want to do, is make sure that your 'Player' game object is above the plane. Now we are going to add the 'Nav Mesh Agent' component to your 'Player' game object, as before select the 'Player' game object click the add component button in the inspector and select 'Nav Mesh Agent'.


With our 'Nav Mesh Agent' component added to our 'Player' game object we can now reference it in our 'Player Controller' game object. Select the player controller and like we did with the Camera reference our Player.


We now have one final step before the super cool step of a moving ball, click on the 'NavMesh' game object we created earlier in the hierarchy and click the 'Bake' button.


Notice the light blue added to our Plane, this is the movable area by our 'Agent' now if you click Play button we can click anywhere on our plane and move our 'Player' game object to that location. 

Test out the demo here
Check out the Source here