- Home /
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;
}
}
Answer by Eno-Khaon · Apr 23, 2017 at 08:27 PM
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;
As an added note: Just in case it applies, you could also factor in a simple dot product test to verify whether you're moving forward or backward:
forwardSpeed *= $$anonymous$$athf.Sign(Vector3.Dot(rb.velocity, transform.forward));
Dear Eno-$$anonymous$$haon,
Thank you for your reply. As I am new to unity, I got your logic but i didn't get how can I put your given solution to the script? Can you please give me little more info so that I can have better idea how can I use your solution.
Thank you
You accidentally posted an answer to your question. I converted your answer into a comment.
I'm not sure what else you need to know. forwardVelocity
is a vector that is parallel to the objects forward vector and it's length is only the portion of the velocity that moves the object along that axis.
So forwardSpeed
is the numerical value which you asked for.
Answer by MaartenB · Apr 24, 2017 at 07:49 AM
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);
}
That doesn't make much sense. It only gives you the world axis aligned component of the velocity. If you imagine "+z" to be "north" that component would be 0 when you drive "east-west" / "west-east".
Answer by Bunny83 · Apr 23, 2017 at 08:59 PM
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;
Dear Bunny83, Thank you for your reply.
I understand that forwardVelocity is vector. But how can I define the answer in my script? Because I am new to unity and I have started to use unity since one week and all I learnt is from the FAQ and tutorials. I am very new to coding as well. So I don't have good basic knowledge of the coding. So I understand what is the logic behind adding the answered script into my script but I don't have any idea that how I can I implement this into my script. I searched all the command into unity documentary and trying to get idea but I am still trying to understand how to put the answered script into my script. Actually this is my school project so I have to do it. I am currently studying and I am from Industrial Engineering department and I don't know why my professor wants me to do Coding and developing a game!!!! That is why I am stuck, not able to understand, takes more time to understand.
Thank You
I've edited my answer and included the changes you most likely want.
Note: You again posted an answer to your question ins$$anonymous$$d of a comment to my answer. The "answer" function at the bottom of the page is only for posting answers to the question at the top. For everything else you should use comments. Every answer has an "Add comment" button below. Furthermore comments have a "reply" button at the top when you hover with your mouse over the comment. Both allow you to add a comment to that post.
I just replied to your comment (which i converted previously from an answer). Please have a look at the site navigation guide which is also linked on the right side.
Answer by Arycama · Apr 24, 2017 at 11:24 AM
Change your Speedometer update function to this:
void Update ()
{
image.fillAmount = rb.transform.InverseTransformDirection(rb.velocity).z;
}
Dear Arycama,
Thank you so much for your response. I updated your given function to Speedometer script but it didn't worked. Have I need to change anything in in the script of Bicycle?
Thank you
Your answer
Follow this Question
Related Questions
How to change colors in unity using photon? 0 Answers
Input.GetMouseButton(0) registering twice on relase? 4 Answers
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Detect small targets with Vuforia 0 Answers