Add a marker below your car to better know it's position
Add a marker below your car to better know where it is.
Updated: Aug 12, 2023
Published: Aug 5, 2023
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.
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.
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.
We then need to attach that texture to a new material, and add it to a game object. Follow these steps
- Add the circle image (as PNG to keep transparency values) to your Unity project
- Create a new material
- Drag the circle image onto the material (onto the Albedo checkbox)
- Change the material shader to Unlit --> Transparent
- Attach the material to a new empty game object, (e.g.
Car Circle
,) and add it to your car
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!