I made this script for a freelancer project originally, which was a sailing game with pirates and ships. We needed a compass, and we wanted to show the player, how the wind affects his sailing speed.
The basic idea here is to have a horizontal grid layout with Text elements. I call this the ribbon. The script moves this ribbon horizontally based on where the character is facing.
The problem I encountered is circularity. I wanted to translate from the end of the ribbon to its start seamlessly. The setup below resulted in a failure, the compass ran out of letters.
SE — S — SW — W — NW — N — NE — E —
I figured out I have to make duplicates. I only move the ribbon between the two S letter and let the overflowing part simulate the circularity.
The script
public class RibbonCompass : MonoBehaviour { [SerializeField] Vector3 NorthDirection = new Vector3(0,0,1); [SerializeField] Transform Actor; [SerializeField] GridLayoutGroup ribbon; float _angleMultiplier; void OnEnable() { _angleMultiplier = 2 * ribbon.cellSize.x / 45; } void Update() { Vector3 actorDirection = Actor.forward; float angle = Vector3.SignedAngle(actorDirection, NorthDirection, Vector3.up); Vector3 ribbonPosition = ribbon.transform.localPosition; ribbonPosition.x = angle * _angleMultiplier; ribbon.transform.localPosition = ribbonPosition; } }
The script is pretty simple. We need three variable for the inspector:
- The direction of the north: as default, I set it to Vector3.forward.
- The actor transform. We’ll compare it’s forward direction to the north direction.
- The ribbon. This will be a GridLayoutGroup.
We also need a private variable to store the angle multiplier. I’ll explain it later but first, let’s see what this script does.
- Calculates the angle between the actors forward and the north direction.
- Then sets the ribbon position in a way to show the right letter.
I’m using text game objects for the letters and for the separators (—). Each of these cells has the same width value, defined in the GridLayoutGroup.
Between North and North West there is 45 degrees difference in angle. If I’m staying in the center of the N letter, I have to move 2 cells:
- I move the ribbon half cell to arrive at the start of the separator.
- One full cell (the separator).
- Half cell again to reach the center of the NW cell.
That’s being said, every 45° needs to move the ribbon with 2 cell width. Instead of calculating each time in the update function, I precalculate this and store it on the _angleMultiplier variable.
How to use the component
The component you can download from the Gumroad (for free) has a slightly better inspector, and also contains the color changing feature.
- Ribbon: The Grid Layout Group that contains your cells.
- Special direction: The script will change the marker color from the default to the special when the Actor faces to this direction.
- Color Blend: With this curve, you have more control how the two color should blend into each other.