• Register
Post news RSS Arrival in Hell: Dev Blog #1: Navigation

I'm remaking the 2006 Flash game, Arrival in Hell, in 3D. This is my first full project in Unity so I've decided to share my experiences with some technical write-ups. This first one explains how I went about implementing navigation. I'm used to manually programming this myself but Unity offers a great built-in system, so I go into detail on how I've used it.

Posted by on

Hello and welcome to the first instalment of the Arrival in Hell dev blog. Even though we've been working on Arrival in Hell in our spare time for over a year now, I wanted to kick off the dev blog from the beginning so you get a much fuller picture of how the game works.

In case you don’t know already, I’ll quickly summarize what we’re making. It’s a remake of a 2006 Flash game originally created by my friends Eduardo Mojica and Richard Rout. It is a horror point-and-click adventure game and we’ll be building it in Unity. I've been programming and making games for about 10 years now, but this is my first project in Unity.

The first thing I wanted to nail down early, before anything else, was the player movement. Since the game is now true 3D, the player needs to path find in 3D space. Luckily Unity already has awesome pathfinding functionality built in. To use it you simply open Window > Navigation, select objects you want to be included in the path finding and check them as ‘Navigation static’. This tells Unity that these objects are static (not moving) and should be taken into account when pathfinding.

Setting objects to 'Navigation Static'Setting objects to ‘Navigation Static’


I’d like to take a moment to express just how awesome this is. In the past I, like most game developers, have had to build my own path finding system. I've done A* tile and node based pathfinding systems before, and in both cases, particularly node based, setting up the ‘walls’ has been a real pain. With a node based system you have to manually place points used by the AI to navigate between. Not only does Unity come with navigation out of the box, it also uses navigation meshes, which are far more efficient and smooth than manually placed nodes. To top it all off, you can re-bake (recalculate) the entire nav mesh by clicking one button. Gone are the days of manually fiddling with navigation nodes!

One of my less successful attempts at node based pathfinding
One of my less successful attempts at node based pathfinding


Once you've marked static objects to be included in the nav mesh, you choose a few settings (such as how steep a slope can be and how high a step can be before it’s considered a wall) and hit the bake button. This will generate your nav mesh which you can preview in the scene view. One thing worth noting is that just because an object exists in the scene, doesn't mean it has to be part of the nav mesh. For example in the game I don’t care if the player walks over rubble, so I have not marked any rubble objects as navigation static; this speeds up the nav mesh generation.

These are the actual values used in Arrival in Hell
These are the actual values used in Arrival in Hell


Baked NavMesh. Unity does an excellent job of automatically generating this
Baked NavMesh. Unity does an excellent job of automatically generating this


Once the nav mesh was generated I simply added a NavMeshAgent component to the player model. The game is now set up for navigation. The only thing left is adding mouse input to control the destination of the NavMeshAgent.

NavMeshAgent settings
NavMesh Agent settings


To tell the nav mesh agent where to navigate to I:

  1. Listen for mouse input
  2. Get the mouse position in screen space
  3. Convert the screen space coordinate to a ray from the camera
  4. Cast the ray out until it hits the floor
  5. Set the NavMeshAgent’s destination to that position on the floor

The C# code looks a little like this:

void Update () {
    if (Input.GetMouseButton(0))
    {
        Vector3 screenPoint;
 
        screenPoint = Input.mousePosition;
 
        Ray ray = Camera.main.ScreenPointToRay(screenPoint);
 
        RaycastHit hitInfo;
 
        if (floor.GetComponent().Raycast(ray, out hitInfo, 10000.0f))
        {
            Vector3 targetPoint = ray.GetPoint(hitInfo.distance);
            agent.SetDestination(targetPoint);
            agent.Resume();
        }
    }
}

Click to set NavMeshAgent's destination
Click to set NavMeshAgent’s destination


You can visualize the destination and path in the scene view
You can visualize the destination and path in the scene view


This handles pretty much all of the navigation needs of the game. The only exception is when the nav mesh changes due to some event in the game. For example the cell door is initially closed in the first room. Later when it’s opened, the nav mesh needs to update to reflect this change and to allow the player to walk through the now open door. Rather than re-baking the entire static nav mesh at runtime, I have made use of the ‘NavMeshObstacle’ component. This component allows you to include ‘dynamic’ objects in the path finding. If the object moves, Unity’s pathfinding algorithm updates accordingly on the fly.

Navigation paths are updated automatically with changes to NavMeshObtacle
Navigation paths are updated automatically with changes to NavMeshObtacle


Visualisation of NavMeshObstacle changes in scene view
Visualisation of NavMeshObstacle changes in scene view


And there we have it; this is how the navigation works in Arrival in Hell. All of this is achieved using out of the box navigation functionality supplied with Unity. I've made the example shown above available
here in case anyone wants it. Next week I’ll be detailing how room changes and camera angles work.

Post a comment
Sign in or join with:

Only registered members can share their thoughts. So come on! Join the community today (totally free - or sign in with your social account on the right) and join in the conversation.

News
Tags
Dev Diary
Browse
News
New
Post news
Share
Related Games
Arrival in Hell
Arrival in Hell Point and Click
Related Engines
Unity
Unity Commercial