# Implementing an Overworld Compass in Unity

Published

When moving around in an expansive world in a game, there are 2 common solutions to help the player orientate: a minimap, or a compass.

In this article we’ll focus on implementing a compass, as it is simple and can feel much more authentic in a fantasy RPG than a full-blown minimap with objects and ennemies tracking.

You can also implement cool effects, such as making the Compass indicator spin like crazy to indicate treasure.

## From Player Orientation to Cardinal Direction

A compass is a fairly simple tool: wherever the player might be looking towards, it will always point North. To do this, we’ll create a canvas and an image with a compass texture. Then we’ll rotate the compass image on its z-axis, according to changes in the player’s orientation.

## Implementation

To do what we just described, we’ll create a Monobehaviour component that will transform the player’s forward into a rotation angle. If we consider North as being in the direction (0, 0, 1) in world space, then we can get the player’s forward, set the y value as 0, and normalize it.

By doing this, we can consider both points as being on a circle and use Mathf.Atan2 to get the angle by which we must rotate our sprite following the z-axis.

Then we’ll need to do a final adjustment: this angle calculation gives us the angle relative to the x-axis, so we need to add 90 degrees to set it relative to the z-axis.

This gives us the following code:

``````public class Compass : MonoBehaviour
{
public Transform mPlayerTransform;

[Tooltip("The direction towards which the compass points. Default for North is (0, 0, 1)")]
public Vector3 kReferenceVector = new Vector3(0, 0, 1);

// memalloc
private Vector3 _mTempVector;
private float _mTempAngle;

// Update is called once per frame
private void Update()
{
// get player transform, set y to 0 and normalize
_mTempVector = mPlayerTransform.forward;
_mTempVector.y = 0f;
_mTempVector = _mTempVector.normalized;

// get distance to reference, ensure y equals 0 and normalize
_mTempVector = _mTempVector - kReferenceVector;
_mTempVector.y = 0;
_mTempVector = _mTempVector.normalized;

// if the distance between the two vectors is 0, this causes an issue with angle computation afterwards
if (_mTempVector == Vector3.zero)
{
_mTempVector = new Vector3(1, 0, 0);
}