• News
  • Games
  • About
  • Cover image

    Add a marker below your car to better know it's position

    Add a marker below your car to better know where it is.

    I was having trouble knowing where the car was headed when it was jumping high in the air. In order to solve the problem, we can add a marker below the car. It's important to keep marker leveled to the ground. In our example, we create a circle as our marker.

    blog post image

    We see the same technique on the ball in Rocket League. When the ball is high in the air, it's difficult to know it's location. Adding a marker below it will help with that. In Rocket League, the inner circle will also shrink the higher the ball is, similar to how a shadow would be cast.

    blog post image

    We can do the same in Unity, and the solution is easy. First, we need to create a marker in a photo editing tool (I used Affinity Photo.) Give to circle a large resolution to make it scale better without loosing quality.

    blog post image


    We then need to attach that texture to a new material, and add it to a game object. Follow these steps

    1. Add the circle image (as PNG to keep transparency values) to your Unity project
    2. Create a new material
    3. Drag the circle image onto the material (onto the Albedo checkbox)
    4. Change the material shader to Unlit --> Transparent
    5. Attach the material to a new empty game object, (e.g. Car Circle,) and add it to your car
    blog post image

    We now need to create some code to make the marker stay at ground level, directly below the car. I've created a CarCircle.cs script to help us with that. The script should be attached to the same object we added our custom material to.

    CarCircle.cs

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class CarCircle : MonoBehaviour
    {
    
        // This point can be an empty game object on your car
        [SerializeField] Transform groundRayPoint;
    
        // This is the layer you want to check a collision against
        public LayerMask whatIsGround;
        public float groundRayLength = 10f;
        private float groundOffsetY = .2f;
    
        // We use FixedUpdate instead of Update because we need to cast a ray using Physics
        private void FixedUpdate()
        {
            // Create a ray
            // Send directly below the car towards the ground
            // Use the hit (collision) to position the marker
            RaycastHit hit;
            if (Physics.Raycast(groundRayPoint.position, -groundRayPoint.transform.up, out hit, groundRayLength, whatIsGround))
            {
              
                // Make the marker rotate according the slope of the road 
                transform.rotation = Quaternion.FromToRotation(groundRayPoint.transform.up, hit.normal) * groundRayPoint.transform.rotation;
              
                // Move the marker to the correct position, 
                // where the ray hit the ground.
                // Add a slight offset to the y-position
                transform.position = new Vector3(groundRayPoint.position.x, hit.point.y + groundOffsetY, groundRayPoint.position.z);
            }
        }
    }
    

    With this, we'll be able to more easily identify where our car is. The circle also serves a different purpose in my car racing game. When we compete against many other similar cars, it can be difficult to identify where our own car is among all of them. The circle will only be displayed on our own car, not the other ones, making it easy to know which car we're actually controlling. The same technique can be used on any object in your game.

    If you liked this blog post, or want me to elaborate on other topics, consider following me on Twitter, @ReitGames, and mention me in a Tweet. Happy coding!