How do I measure the velocity in Z-direction?

I am new to unity.

I have made a bicycle moving and I am putting a speedometer for that. The idea I used is detecting the velocity of an object and transfer it into angular movement. But the problem is that the speedometer is detecting the direction in Y-Direction (Like if I remove the gravity from rigid body, the bicycle goes downward and the speedometer is showing the speed). Here I want to measure the velocity of bicycle win Z-Direction.

Here I am adding two scripts which I used for Bicycle to move and another one for speedometer I put in.

Please help me through this.

Thank You

C# Script : Bicycle
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerFinalDuplicate_2 : MonoBehaviour {

public Animator anim;
Rigidbody rb;
public float speed = 50f;            
public float rotationSpeed = 180f; 
public float translationRate = 10f;

private bool run;
private float inputH;
private float inputV;

private string m_MovementAxisName;     
private string m_TurnAxisName;         

private float m_MovementInputValue;    
private float m_TurnInputValue;

private void OnEnable ()
{

	m_MovementInputValue = 0f;
	m_TurnInputValue = 0f;
}

// Use this for initialization
void Start () 
{
	anim = GetComponent<Animator>();
	rb = this.GetComponent<Rigidbody>();
	run = false;

	m_MovementAxisName = "Vertical";
	m_TurnAxisName = "Horizontal";

}
	
// Update is called once per frame
private void Update()
{
	if (Input.GetKey (KeyCode.LeftShift)) {
		run = true;
	} else {
		run = false;
	}

	inputH = Input.GetAxis ("Horizontal");
	inputV = Input.GetAxis ("Vertical");

	anim.SetFloat ("inputH", inputH);
	anim.SetFloat ("inputV", inputV);
	anim.SetBool ("run", run);

	float moveX = inputH * speed * Time.deltaTime;
	float moveZ = inputV * speed * Time.deltaTime;

	if (moveZ <= 0f) {
		moveX = 0f;
	} else if (run) {
		moveX *= 2f;
		moveZ *= 2f;
	}

	float translation = Input.GetAxis ("Vertical") * speed;
	translation *= Time.deltaTime;
	rb.AddForce (this.transform.forward * -translation*translationRate);

	// Store the player's input and make sure the audio for the engine is playing.
	m_MovementInputValue = Input.GetAxis (m_MovementAxisName);
	m_TurnInputValue = Input.GetAxis (m_TurnAxisName);

}
private void FixedUpdate()
{
	// Move and turn.
	//Move ();
	Turn();
}

private void Turn()
{
	// Adjust the rotation of the tank based on the player's input.

	float turn = m_TurnInputValue * rotationSpeed * Time.deltaTime;

	Quaternion turnRotation = Quaternion.Euler (0f, turn, 0f);

	rb.MoveRotation (rb.rotation * turnRotation);
}

}

C# Script : Speedometer

Here I set the the image filling for measuring the velocity.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class SpeedImage : MonoBehaviour
{
public Rigidbody rb;
public float minVelocity = 0.0f;
public float maxVelocity = 10.0f;

private Image image;

// Use this for initialization
void Start () 
{
	image = GetComponent<Image>();
}

// Update is called once per frame
void Update () 
{
	image.fillAmount = rb.velocity.magnitude/maxVelocity;

}

}

Fortunately, this is actually fairly simple to implement, thanks to Vector Projection. Specifically, in this case, Vector3.Project().

Take your velocity vector, rb.velocity, and project it onto your forward vector, transform.forward. The magnitude of that vector is your forward velocity.

Vector3 forwardVelocity = Vector3.Project(rb.velocity, transform.forward);
float forwardSpeed = forwardVelocity.magnitude;

If you want to measure the velocity in the Z-axis, you can use:

private Rigidbody rb;

private void Update()
{
       Debug.Log("The velocity in the Z-axis is: " + rb.velocity.z);
}

Vector3.Project is one way as Eno showed in his answer. Another way is to simply transform the worldspace velocity vector into localspace. That way you have the velocity split into its 3 components, but locally:

Vector3 localVelocity = tranform.InverseTransformDirection(rb.velocity);

So localVelocity.z gives you the signed velocity along the local z axis, and localVelocity.x the signed velocity to the right.

edit
Since you still seem to have trouble how to use the local velocity…

You simply replace your “old” velocity by the “new” one. So in this line:

image.fillAmount = rb.velocity.magnitude / maxVelocity;

you would replace rb.velocity.magnitude with localVelocity.z. Just like this:

Vector3 localVelocity = rb.tranform.InverseTransformDirection(rb.velocity);
image.fillAmount = localVelocity.z / maxVelocity;

Change your Speedometer update function to this:

 void Update () 
 {
     image.fillAmount = rb.transform.InverseTransformDirection(rb.velocity).z;
 }