- Home /
Trying to figure out what direction an NPC are walking
Hi, i am trying to figure out what direction an NPC are "heading"(Forward, Backward and so on) depending on where he is looking.
This is my progress so far:
var temp = (transform.position - lastPosition);
if((transform.rotation.eulerAngles.y > 90f && transform.rotation.eulerAngles.y < 270f)){ temp = new Vector3(temp.x,temp.y,temp.z *-1); }
So what i am trying to do is calculate if the NPC is moving forward or backwards. I take the move Vector (current position - last position) and i look at the z variable of it. So depending of what rotation the NPC are facing, i change the sign of z so if i walk forward the z is always positive , and if i walk backwards its always negative. Ofc i am not using "temp" to move the character, only to see what he is doing.
But i have a problem , when the eular angle is 90 and 270, the sign get messe up and are showing wrong value, and when i rotate the NPC fast while walking.
Any idea how i can fix this?
Answer by Mortoc · Jul 07, 2012 at 10:07 PM
You want to detect direction of vectors by using the dot product.
if( Vector3.Dot(transform.forward, Vector3.forward) > 0.0f )
// dude is walking forward
Here's a pretty clear way to learn about dot product: http://www.youtube.com/watch?v=KDHuWxy53uM&feature=player_embedded
Update
I misunderstood what you meant by "walking forward", I was thinking forward in relation to the world, you're just checking to see if they're walking forward or walking backwards in relation to their forward vector. When taking the Dot between two normalized vectors, the result will be the cosine of the angle between the vectors. (Ex. Vector3.Dot(Vector3.forward, Vector3.up) == 0.0f).
The cosine function gives us +1 at 0° (when the two vectors are the same) and a -1 at 180° (when the two vectors are facing opposite directions) and at -90° and 90° it'll give us 0.
Hopefully a little more complicated example will show the relationship between dot product and angle between vectors.
// You can use rigidbody.velocity or a local variable to keep track of current velocity
float forwardDotVelocity = Vector3.Dot(transform.forward, rigidbody.velocity.normalized);
if( forwardDotVelocity > Mathf.Cos(60.0f) )
// Facing forward
else if( forwardDotVelocity < Mathf.Cos(120.0f) )
// Facing sideways
else
// Facking backwards
When i test the code , it only change value when i rotate the npc, not when he is moving.
Just use the Dot Product on the movement vector you say you are calculating rather than transform.forward.
It seems to have the same problem that my code in my first post have. At certain euler angles, for example 270, the value turns negative. And if the object rotates to fast, it also becomes negative.
Hmm well those are the points at which the Dot product would turn negative - you might be better off using the Acos of the Dot product which will give you the angle of movement of the vectors compared to each other. The problem is that it is the angle between them, so there is no -90 etc.
Your answer
Follow this Question
Related Questions
Problem combining transform.rotation and hierarchical rotations 2 Answers
Relative Rotation 1 Answer
Look rotation viewing is zero warning 0 Answers
Reset position and direction 2 Answers