In my top down 3D game I have the player that faces the direction he is running (WASD). If I hold the the mouse button on a point on the screen it introduces a look point for the character and I’ve set it up so that if the mouse point it move to behind the character while he is moving he flips direction he is facing so that he is effectively running backward. My problem comes in that if the mouse goes around one side of him he rotates (even if quickly, this doesn’t bother me) fine, but if I go around the other he sort of snaps to the reverse side. I’m assuming this has something to do with always rotating around in a certain directing to the point he’s looking at. Is there a way to fix this?
It depends completely on your character controller, and you say nothing about that.
I’m just not sure what info is needed. I’ll see if I can grab the movement and rotation function. I just have to find the code I had before I started butchering it with different attempts XD
Why do you need to make assumptions about your own code. As if somebody else wrote it and you don’t understand it well enough to describe what it’s supposed to do.
Okay this is what I had with the problem persisting.
private void HandleRotation()
{
Vector3 positionToLookAt;
positionToLookAt = currentMovement;
positionToLookAt.y = 0f;
Quaternion reverseRotation = Quaternion.LookRotation(-positionToLookAt);
Quaternion movementRotation = Quaternion.LookRotation(positionToLookAt);
mouseLook = cursorDir;
mouseLook.y = 0f;
Quaternion mouseLookRotation = Quaternion.LookRotation(mouseLook);
if (movementPressed && !altClickPressed)
{
transform.rotation = Quaternion.Slerp(transform.rotation, movementRotation, Time.deltaTime * turnSpeed);
secondryRotation = movementRotation;
}
else if (altClickPressed && !runningBackward)
{
transform.rotation = Quaternion.Slerp(transform.rotation, movementRotation, Time.deltaTime * turnSpeed);
secondryRotation = mouseLookRotation;
}
else if(altClickPressed && runningBackward)
{
transform.rotation = Quaternion.Slerp(transform.rotation, reverseRotation, Time.deltaTime * turnSpeed);
secondryRotation = mouseLookRotation;
}
movingLookAngle = Quaternion.Angle(secondryRotation, movementRotation);
Vector3 crossProduct = Vector3.Cross(currentMovement, mouseLook);
if (crossProduct.y > 0f)
{
movingLookAngle = -movingLookAngle;
}
if (previousLookAngle != movingLookAngle)
{
//Debug.Log(movingLookAngle);
previousLookAngle = movingLookAngle;
}
if (movingLookAngle < -90 || movingLookAngle > 90 && movementPressed)
{
runningBackward = true;
}
else
runningBackward = false;
}
Oh I understand the code. I’m by no means an expert so some small things that might seems obvious to people might glaze over me but learning is always a thing.
If I read your code correctly, you are using Quaternion.Angle to determine the angle and Vector3.Cross to determine the sign of the angle. There is a direct method to achieve this: Vector3.SignedAngle.
What happens when the angle passes 180 degrees? Using Vector3.SignedAngle it is guaranteed that the value is always between -180 and 180. But in your code I think the angles between two rotations will go over 180, so you can have angles like -1234 there. You can add some debug lines to see if this is the case. In any case I recommend using SignedAngle.
The Quaternion.angle is giving me an angle from my characters direction he’s moving to my mouse cursor. I noticed the angle was always positive regardless if it was moved to the left or right side of him. So I used the Vector3.Cross to to make it negative on one side and positive on the other.
This worked to get a handle on angle my mouse cursor was pointed in relation to the character. I just did some modifications while playing around with something else and the result changed. instead of anything on the right been 0 to 180 and the left been 0 to -180. 12oclock to 3oclock is 0 to -90, 3oclock to 6 is 90 to 180, 12oclock to 9 is 0 to 90 and 9oclock to 6 is -90 to -180. This in itself is actually useful if I feel like adding a bunch of backward strafing animations lol. But I’m not going to blindly use this outcome until I realise why it’s doing this =P
Well. I used the signed angle. Got the same as what I had originally with fewer steps. Thanks for the info.