Manual Player Movement
This page describes how to move a character manually using the A* Pathfinding Project.
Contents
Introduction
In your game, you may want to control the player character using the keyboard or a game pad, or perhaps using point-and-click movement. This tutorial describes a few different setups that you can use.
Case studies
Keyboard movement with pathfinding
Using the keyboard to move a character is a common way to control characters in games. It is often used in action games, platformers, and other games where the player directly controls the character's movement. Usually the WASD or arrow keys are used to move the character.
To achieve this, you can use one of the built-in movement scripts, and continuously set the destination of the agent to a point a few meters away from the character, in the direction indicated by the current keyboard input.
using UnityEngine;
In the video, you can see the current path in orange. Note how, even when trying to move into an obstacle, the agent will automatically move around it. This is a significant advantage of using pathfinding even for these very short paths.
using Pathfinding;
public class PlayerMovement : MonoBehaviour {
public float lookaheadDistance = 1f;
IAstarAI ai;
void OnEnable () {
ai = GetComponent<IAstarAI>();
}
void Update () {
// Check the current keyboard input
var dx = Input.GetAxis("Horizontal");
var dz = Input.GetAxis("Vertical");
// Get the first enabled camera
var cam = Camera.allCameras[0];
// Calculate movement directions relative to the camera
var forward = cam.transform.forward;
forward.y = 0;
forward.Normalize();
var right = cam.transform.right;
right.y = 0;
right.Normalize();
// Set the destination of the AI to a point a few meters ahead of the character,
// in the desired direction.
ai.destination = transform.position + (dx * right + dz * forward) * lookaheadDistance;
}
}
Note
This method works best with the FollowerEntity movement script, due to how it repairs its path automatically every frame, leading to very responsive movement.
If you have other NPCs in your game, you may want to use local avoidance to make the NPCs avoid the player character. Typically, you don't want the player to avoid NPCs, though.
This can be done by changing the local avoidance settings, which are either on the RVOController component, or directly on the FollowerEntity component if you are using that movement script.
In particular, on the player character, we want to drag the priority up to maximum, and set the Collides With mask to Nothing. This will make the player ignore all other agents, but other agents will still avoid the player, and prioritize avoiding the player over other agents.
Keyboard movement without pathfinding
Using your own movement code for the player character, instead of using any of the built-in movement scripts, is also possible.
In this case, you may also want to integrate with local avoidance to make the other agents in your game avoid the player character.
You can do this by attaching an RVOController component to the player character. In your movement code, you can then manually set the RVOController's velocity to the desired velocity of the character. Setting the velocity manually will make the local avoidance system mark this agent as manually controlled, and other agents will just have to deal with it.
Note
You have to set the velocity every frame, or the local avoidance system will think the agent is not manually controlled anymore.
void Update () {
If you also want to clamp your agent to the navmesh, you could use the NavmeshClamp component.
var x = Input.GetAxis("Horizontal");
var y = Input.GetAxis("Vertical");
var v = new Vector3(x, 0, y) * speed;
// Override the RVOController's velocity. This will disable local avoidance calculations for one simulation step.
rvo.velocity = v;
transform.position += v * Time.deltaTime;
}
Point and click movement
Point and click movement is a common way to move characters in games. It is often used in strategy games, RPGs, and other games where the player does not directly control the character's movement.
This is a perfect use case for using the built-in movement scripts in the A* Pathfinding Project, and is very simple to implement.
Whenever you want to move your player to a point, you can set the destination property on the movement script to this point.
void PointAndClick (IAstarAI ai) {
// Check if the mouse button is pressed
if (Input.GetMouseButton(0)) {
var cam = Camera.main;
LayerMask mask = -1;
// Shoot a ray from the cursor, to see where in the world it hits
if (Physics.Raycast(cam.ScreenPointToRay(Input.mousePosition), out var hit, Mathf.Infinity, mask)) {
// Set the destination of the AI to the point where the ray hit
ai.destination = hit.point;
}
}
}
See
The TargetMover component is used in the example scenes to provide this kind of movement.
Local avoidance can be handled in the same way as in Keyboard movement with pathfinding.