Determin movement direction from two vectors accouting for rotation
I have a character that I move with WASD and rotate direction with mouse. I'm trying to determine which direction the character is moving (ex, forward, backward, left, right) based on it's current and previous position vectors. I tried this code:
Vector3 direction = (gameObject.transform.position - previousPosition).normalized;
if (direction.z == 1)
{
//forward
AnimateWalk(true, false);
}
if (direction.z == -1)
{
//backwards
AnimateWalk(false, true);
}
if (direction.z == 0)
{
//no forward no back
AnimateWalk(false, false);
}
if (direction.x == 1)
{
//right
}
if (direction.x == -1)
{
//left
}
if (direction.x == 0)
{
//no left right
}
previousPosition = gameObject.transform.position;
It works great if I walk in a straight line but if I rotate the character the normalized value will changed based on the rotation and so I need to take the rotation into account some how.
I need something that will give me results something along the lines of:
Forward = 1 Backward = -1 No change = 0 Left = -1 Right = 1 No change = 0
I've tried various methods suggested on the forums and here but had no luck in producing something that will work. The main reason why I want to play the animation this way is because this is a multiplayer game with an authoritative server and instead of sending an RPC every time a new player direction animation is to be played I can have the client determine the proper animation from the gameObjects last and current position vectors.
EDIT: If it helps the character is being moved using the transform.forward and transform.right vectors.
Answer by IronBeard · Feb 08, 2017 at 05:24 PM
After many hours of searching I found the anwser to my question in another post.
You can view the solution here from Piflik as well as below: http://answers.unity3d.com/questions/290226/compare-movement-direction-to-aiming-direction.html
curAngle = Vector3.Angle((curPos - lastPos).normalized, transform.forward);
clockwise = angleDir(transform.forward, (curPos - lastPos).normalized, Vector3.up);
if(curAngle < 30)
animation.CrossFade("walk_F", 0.1);
else if(curAngle > 30 && curAngle < 90 && clockwise < 0)
animation.CrossFade("walk_FL", 0.1);
else if(curAngle > 30 && curAngle < 90 && clockwise > 0)
animation.CrossFade("walk_FR", 0.1);
else if(curAngle > 90 && curAngle < 150 && clockwise < 0)
animation.CrossFade("walk_BL", 0.1);
else if(curAngle > 90 && curAngle < 150 && clockwise > 0)
animation.CrossFade("walk_BR", 0.1);
else if(curAngle > 150)
animation.CrossFade("walk_B", 0.1);
function angleDir(fwd: Vector3, targetDir: Vector3, up: Vector3) {
var perp: Vector3 = Vector3.Cross(fwd, targetDir);
var dir: float = Vector3.Dot(perp, up);
if (dir > 0.0) {
return 1.0;
} else if (dir < 0.0) {
return -1.0;
} else {
return 0.0;
}
}
Answer by hexagonius · Feb 07, 2017 at 10:35 PM
as I understand it, 44° to the right would still be forward. so your bounds are the diagonals. and you're checking in world space. that means you can just use the vector components. (pseudocode):
if Mathf.Abs(x) > Mathf.Abs(z){
if x > 0 right,else left
}
else
if z > 0 forward, else backwards
Unfortunately that doesn't produce the right results for what I need. If I hold forward and rotate direction with the mouse it will cycle though all directions forward, backward, left right depending on the rotation of the gameObject. The code I used is:
Vector3 direction = (gameObject.transform.position - previousPosition).normalized;
if ($$anonymous$$athf.Abs(direction.x) > $$anonymous$$athf.Abs(direction.z))
{
if (direction.x > 0)
{
//right
Log.Debug("right");
}
else
{
//left
Log.Debug("left");
}
}
else
{
if (direction.z > 0)
{
//forward
Log.Debug("forward");
}
else
{
//backwards
Log.Debug("backward");
}
}
EDIT: Just realized you probably meant for the gameObject.transform.x and z to be used ins$$anonymous$$d of the direction x and z. Just tried it and it gives the same result.
Your answer
Follow this Question
Related Questions
Mass apply bake into position to all animations 0 Answers
Cant override animations with scripts? 1 Answer
Disable gameObject in animation 0 Answers