In games where players must refer to maps to confidently navigate large terrains, it can be very useful to display a compass in the GUI, presenting a real-time graphical indication of the direction the player is facing. The next screenshot shows a player's third-person controller looking North-West, in between the cube and sphere. The black "blip" circle on the compass indicates that the player is facing this compass direction.
If you need a set of images for this recipe, you'll find two image files in the 0423_04_03
folder. One is a background image of a compass circle, and the other is a black circle image to represent the direction the player is facing.
To display a compass onscreen, please follow these steps:
// Compass.cs using UnityEngine; using System.Collections; public class Compass : MonoBehaviour { public Transform playerController; public Texture compassBackground; public Texture playerBlip; private void OnGUI() { // background displaying top left in square of 128 pixels Rect compassBackgroundRect = new Rect(0,0, 128, 128); GUI.DrawTexture(compassBackgroundRect,compassBackground); GUI.DrawTexture(CalcPlayerBlipTextureRect(), playerBlip); } private Rect CalcPlayerBlipTextureRect() { // subtract 90, so North (0 degrees) is UP float angleDegrees = playerController.eulerAngles.y - 90; float angleRadians = angleDegrees * Mathf.Deg2Rad; // calculate (x,y) position given angle // blip distance from center is 16 pixels float blipX = 16 * Mathf.Cos(angleRadians); float blipY = 16 * Mathf.Sin(angleRadians); // offset blip position relative to compass center (64,64) blipX += 64; blipY += 64; // stretch blip image to display in 10x10 pixel square return new Rect(blipX - 5, blipY - 5, 10, 10); } }
The
Compass
class needs three public variables, the first is a reference to the player's 3rd Person Controller, the other two are images for the compass background image (usually a circle of some kind with the compass letters displayed) and another image to indicate the direction the player is facing on the compass background.
The OnGUI()
method is called every frame, and at each frame the compass background needs to be displayed, followed by the image indicating the player's direction. The position of that "blip" image is calculated and returned by the CalcPlayerBlipTextureRect()
method. Both the images are displayed using the DrawTexture()
method of the GUI
class, which expects a Rect
object and the texture
object. Many recipes result in us knowing the center co-ordinates of a square or rectangle and its size/width/height. Therefore (as the following figure shows) such calculations in this recipe are straightforward to calculate:
This recipe makes use of the "yaw" angle of rotation, which is rotation about the y-axis—that is, the direction a character controller is facing. This can be found in the "y" component of a GameObject's eulerAngles
component of its transform. You can imagine looking from above, down at the character controller, and seeing what direction they are facing—this is just what we are trying to display graphically with the compass. In mathematics, an angle of zero indicates an east direction. To correct that, we need to subtract 90 degrees from the yaw Euler angle. The angle is then converted into radians, since that is required for the Unity trigonometry methods. We then multiply these Sin()
and Cos()
methods' results by the distance we want the blip to be displayed from the center of the compass circle (in our code example, this is 16
pixels). We add 64 pixels to these x and y co-ordinate results since that is the center of the compass' background image. These final values for blipX
and blipY
are the position on screen we wish the center of player's directional blip image to be displayed. Knowing the center of the blip image, and its width and height (both 10 pixels) allows the Rect
object to be created for use by the DrawTexture()
method called from OnGUI()
.
3.22.71.28