Displaying a compass to show player direction

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.

Displaying a compass to show player direction

Getting ready

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.

How to do it...

To display a compass onscreen, please follow these steps:

  1. Create a new scene, and add a directional light.
  2. Create a new terrain, set Size to 2000 x 2000 and Position (-1000, 0, -1000).
  3. Import the built-in Character Controller Unity package.
  4. Add a 3rd Person Controller to your scene at Position (0, 1, 0).
  5. Create a cube in front (North) of the 3rd Person Controller at (0, 1, 5).
  6. Create a sphere to the left (West) of the 3rd Person Controller at (-5, 1, 0).
  7. Attach the following script class to the Main Camera:
    // 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);
     }
    }
  8. With the Main Camera selected in the Hierarchy view, drag the 3rd Person Controller, the compass background image, and the image for the player's direction "blip" into the Inspector view for the three public variables.

How it works...

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:

How it works...

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().

See also

  • The Displaying a radar to indicate relative locations of objects recipe.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.21.106.7