Setting-up Unity FirstPersonController in Terrain

Recently I attempted navigation of the player in Unity using its FirstPersonController component in a terrain environment. I had created character controller from scratch for the player navigation earlier, but wanted to use FirstPersonController because it makes development easy and has many features which can be controlled using configuration settings. And I wanted to do this in a terrain environment using Unity Terrain tools.

I have documented my learnings and steps I took to implement the above in following sections and videos. The focus was more on “How To” than creating a beautiful game scene. The final outcome looked like this –

Importing StarterAssets

Go to the Unity Asset Store and search for “Starter Assets” for First Person. Get the asset pack, open it in Unity and import it from the package manager.

Install Terrain Tools

In the package manager, switch to Packages from “Unity Registry” and search for Terrain Tools. Install the terrain tools. At the end of the installation, it provides an option to “Download Asset Samples from Asset Store”. Click on that button and get the assets from the Asset store. Open them in Unity and import from the package manager.

Import Foliage Tree Pack

I am using tree prefabs from Foliage Pack in this example. Get it from the Unity Asset Store and import it in your project

Create Terrain

Create a terrain object in the scene. Create a new “Ground” layer and set the new terrain created to this layer. Create a few hills/mountains using “Raise or Lower Terrain” option in the “Paint Terrain” tab in the properties inspector. Then add terrain textures by selecting “Paint Texture” from the drop-down and adding multiple texture layers.

Add Trees

Switch to “Paint Trees” tab in the property inspector and add tree prefab. I selected pine2a prefab from Foliage Pack. “Paint” trees in the terrain either using brush at specific locations or “Mass Place Trees”, which will add specified number of trees all over the terrain.

Add Player

Add a player (Capsule) object and set up camera to follow the player.

Set First Person Controller

First add RigidBody component to the player. Then add FirstPersonController component . Here are the steps to configure this component.

  • Add FirstPersonControllerScript from Assets->StarterAssets->FirstPersonController->Scripts to the player
  • In the “First Person Controller” section of Player properties, go to Cinemachine section and drag and drop camera_root object from the Hierarchy to this field
  • In the Ground layer mask field select only “Ground” from the drop-down
  • Set Player Input field to StarterAssets.inputactions
  • From the Assets panel, drag and drop Assets->StarterAssets->InputSystem->StarterAssetsInput.cs on to Player Properties (i.e. add this script to the player object)
  • Open properties for the Main Camera and add “Cinemachine Brain” component to the camera
  • Run the game and check if you are able to navigate the player using up/down/left/right keys

Change Navigation

I wanted to change the default navigation. I did not want camera to look up/down/left/right on mouse movement. Also I did not want the player to move sideways on pressing left/right keys. Instead, I wanted player to turn/rotate after pressing left/right keys. To do this, open the configuration settings panel of “Player Input” by double-clicking “StandardAssets” value (we set this in an earlier step). Then change the configuration settings as explained in the video.

Add Tree Collider

Trees we added from Foliage pack to the terrain either do not have collider or have mesh collider which does not work in terrain. Therefore you will see that player passes through trees instead of being blocked by them.

To fix this, I created a new prefab from existing pine2a prefab. I added capsule collider to this new prefab and changed terrain settings to use this new prefab. After this change, player’s movement is blocked by the trees.

Fix Player Jump

Jump action on the player does not work, because Ground Radius of First Person Controller component of the player is set to 0.5 and origin of the player is at approximately 2 meters height. The script for the First Person Controller checks if the player is on the ground by creating an invisible sphere around the player with radius specified in the above field and checks if any object (from the selected layers, in our case Ground layer) hit the sphere. If the player is not grounded, jump action does not take place. So, setting “Ground Radius” to 3 meters fixes this issue.

Another way to fix this issue is to use Character Controller’s isGrounded method. Change GroundedCheck method in FirstPersonController.cs (in Assets->StarterAssets->FirstPersonController->Scripts folder) as below –

private void GroundedCheck() {
Grounded = _controller.isGrounded;

Add Fog

In the last step I added light fog to the scene by changing Lighting properties. There is a check box to set fog in the Environment tab of Lighting properties. Check this box and adjust the fog density.

-Ram Kulkarni

Leave a Reply