Creating a speedometer ,largely depends whether you want to display a numerical readout, or as a rotating needle.
First, to get the actual speed value, as mentioned in another answer, you can simply use the rigid body’s velocity. However, Unity’s default scale is one unit = one meter, so reading rigidbody.velocity.magnitude
will give you the speed in meters per second.
To convert to MPH, you can use:
1: var mph = rigidbody.velocity.magnitude * 2.237;
Convert to KPH:
1: var kph = rigidbody.velocity.magnitude * 3.6;
Next to display it.
To show the speed as a numerical readout is comparitively simple:
1) Create a GUIText gameobject (from the gameobject menu).
2) In your car script, create a var which will store a reference to this GUIText GameObject:
1: var mphDisplay : GUIText;
3) Select your car, and drag a reference from the new GUIText GameObject in the hierarchy into this variable slot in car script, in the inspector.
4) Now, in your car script, you can add the lines in your Update() function to calculate the MPH, and update the text displayed:
1: var mph = rigidbody.velocity.magnitude * 2.237;
2: mphDisplay.text = mph + " MPH";
That should get you working with a numerical readout.
To display as a rotating needle requires some trickier coordination. There’s no simple way to rotate a GUI Texture, or a texture drawn using the OnGUI method, so I’ve written a small general-purpose script which you can place on a gameobject to create a rotatable GUI Texture. You can control it by setting the ‘angle’ variable from other scripts.
So:
1) Create a new C# script. Name it “RotatableGuiItem”, and paste in this script:
1: using UnityEngine;
2: [ExecuteInEditMode()]
3: public class RotatableGuiItem : MonoBehaviour {
4:
5: public Texture2D texture = null;
6: public float angle = 0;
7: public Vector2 size = new Vector2(128, 128);
8: Vector2 pos = new Vector2(0, 0);
9: Rect rect;
10: Vector2 pivot;
11:
12: void Start() {
13: UpdateSettings();
14: }
15:
16: void UpdateSettings() {
17: pos = new Vector2(transform.localPosition.x, transform.localPosition.y);
18: rect = new Rect(pos.x - size.x * 0.5f, pos.y - size.y * 0.5f, size.x, size.y);
19: pivot = new Vector2(rect.xMin + rect.width * 0.5f, rect.yMin + rect.height * 0.5f);
20: }
21:
22: void OnGUI() {
23: if (Application.isEditor) { UpdateSettings(); }
24: Matrix4x4 matrixBackup = GUI.matrix;
25: GUIUtility.RotateAroundPivot(angle, pivot);
26: GUI.DrawTexture(rect, texture);
27: GUI.matrix = matrixBackup;
28: }
29: }
3) Create a new empty GameObject. Name it “mph needle”. Add the RotatableGuiItem script to it.
4) Assign your speedo needle “Texture” variable. You probably want to use a texture with a transparent alpha background for this, and bear in mind that it will rotate around the centre of the image. Adjust the “size” values to match the size of your texture.
5) Adjust the position of the texture using the X and Y position values of the GameObject in the inspector, so that it is your desired position. (probably in the centre of a normal static GUI Texture showing the mph dial face).
6) In your car script, create a var which will store a reference to this rotatable GUI item:
1: var mphNeedle : RotatableGuiItem;
7) Select your car, and drag a reference from the “mph needle” GameObject in the hierarchy into this variable slot in car script, in the inspector.
8) Now, in your car script, you can add the lines in your Update() function to calculate the MPH, and update the needle’s angle:
1: var mph = rigidbody.velocity.magnitude * 2.237;
2: mphNeedle.angle = mph;
You will probably need to adjust how far the needle turns in relation to the mph, and at what angle it starts, so you may end up with a line which looks more like this:
1: mphNeedle.angle = 20 + mph * 1.4f;
Which means the needle will be rotated by 20 degrees when the mph is zero, and will rotate 1.4 degrees for every 1 mph.
(If you want to control this script from a Javascript script, you’ll have to move the C# RotatableGuiItem into a folder called PlugIns in your assets.)
Hopefully this should get you to the stage where you have a working speedometer with a rotating needle!
Please comment, I have worked hours solving this, if you comment, it will give me some support!