'How can I determine which direction my car transform is moving
I have the transform
for a car with the standard CarController
Component from the UnityStandardAssets.Vehicles
If I move the car and check the Speed from the CarController, it's a positive value for both reversing or accelerating.
What is the correct method to determine whether the transform is moving towards its 'front' or its 'back'?
Solution 1:[1]
Here's a shot in the dark after looking through some of the documentation.
The CarController acts on the RigidBody, and the CurrentSpeed is calculated from the magnitude of the velocity vector and then converted to miles per hour. Magnitude cannot be negative, so you'll need to compare the forward direction of the car to the rigidbody's velocity vector.
If the dot product of 2 normalized vectors is 1, then they are parallel. If the dot product is -1, then they are opposite. If it is 0, they are perpendicular. If it is 0.5f, then they are roughly in the same direction but not quite parallel. If it is -0.5f, then they are roughly in the opposite direction but not quite opposite.
My recommendation would be to check the dot product of the car's normalized forward vector and its rigidbody's normalized velocity vector. If it's greater than 0.5f, then the car is moving mostly forward, if it's less than -0.5f, then the car is moving mosly backwards. If it is between -0.5f and 0.5f, then the car is skidding around mostly sideways.
Rigidbody rb;
string dir;
Start()
{
rb = GetComponent<Rigidbody>();
}
//Since you'll be working with physics (rigidbody's velocity), you'll be using fixedupdate
FixedUpdate()
{
float dotP = Vector3.Dot(transform.forward.normalized, rb.velocity.normalized);
if(dotP > 0.5f)
{
dir = "forward";
}
else if(dotP < -0.5f)
{
dir = "reverse";
}
else
{
dir = "sliding sideways";
}
}
It's probably more valuable to set up an enum for the direction, or just utilize a bool for reverse/forward. You should tailor this to your needs.
This code was freehand, so please let me know of any syntax errors.
Solution 2:[2]
You need to check two parameters. The first vector.dot product of rb.velocity
vector and transform.forward
and next is the minimum speed threshold.
private void CheckDirection()
{
var dot = Vector3.Dot(transform.forward, rb.velocity);
if (rb.velocity.magnitude <= speedThreshold) return;
Debug.Log(dot >= 0 ? "Forward" : "Backward");
}
Solution 3:[3]
This code could be pasted directly into the CarController
script from Unity.
As Erik Overflow pointed out, a good recommendation is to implement a custom controller that inherits the CarController. This way your code doesn't disappear when Unity updates the package
public const string DIRECTION_FORWARD = "forward";
public const string DIRECTION_REVERSE = "reverse";
public const string DIRECTION_SIDESLIDE = "sideslide";
public const string DIRECTION_STATIC = "static";
public string GetMovementDirection() {
float dotP = Vector3.Dot(transform.forward, m_Rigidbody.velocity);
if (dotP > 0.5f) {
return DIRECTION_FORWARD;
} else if (dotP < -0.5f) {
return DIRECTION_REVERSE;
} else if (CurrentSpeed <= 0.99f) {
return DIRECTION_STATIC;
} else {
return DIRECTION_SIDESLIDE;
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | KiynL |
Solution 3 |