- Home /
Problem with rotation Please Help Me
I have a GameObject "Player" that is the parent of an Image "The Red". I use the Player for the movement. and The Red for the rotation. When I press, WASD keys, it will move and rotate towards where it is moving. When I rotate from 0 degrees to 270 degrees, there is no problem, it rotates counter clockwise. but when I rotate from 270 degrees to 360 degrees then it will rotate clockwise instead of counter clockwise which is closer. I think there is something that I need to take the difference of but I don't know what.
This is what it looks like from the Game.
https://media.giphy.com/media/l4FGkuEF9bk2dWk1O/giphy.gif
This is my PlayerMovement.cs Script
public class PlayerMovement : MonoBehaviour { public float moveSpeed; public GameObject theRed;
void Update()
{
Vector3 movement = new Vector3 ();
Vector3 rotation = Vector3.zero;
if(Input.GetKey(KeyCode.W))
{
movement += Vector3.up;
rotation.z = 90f;
theRed.transform.localEulerAngles = Vector3.Slerp(theRed.transform.localEulerAngles, rotation, 0.15f);
}
else if(Input.GetKey(KeyCode.S))
{
movement += Vector3.down;
rotation.z = 270f;
theRed.transform.localEulerAngles = Vector3.Slerp(theRed.transform.localEulerAngles, rotation, 0.15f);
}
else if(Input.GetKey(KeyCode.A))
{
movement += Vector3.left;
rotation.z = 180f;
theRed.transform.localEulerAngles = Vector3.Slerp(theRed.transform.localEulerAngles, rotation, 0.15f);
}
else if(Input.GetKey(KeyCode.D))
{
movement += Vector3.right;
rotation.z = 0f;
theRed.transform.localEulerAngles = Vector3.Slerp(theRed.transform.localEulerAngles, rotation, 0.15f);
}
transform.Translate (moveSpeed * movement.normalized * Time.deltaTime);
}
}
Update: I finally fixed it and got it working the way i wanted to. I'm using WASD keys for the movement. Thank you sirs!
Here is what is looks like: https://media.giphy.com/media/3ohzdJvzwjh$$anonymous$$lEUAbC/giphy.gif
Here is the code in case anyone runs into the same problem.:
public class $$anonymous$$OVE : $$anonymous$$onoBehaviour { public float moveSpeed; public GameObject theRed;
void Update ()
{
float moveH = Input.GetAxisRaw ("Horizontal");
float moveV = Input.GetAxisRaw ("Vertical");
Vector3 movement = new Vector3 (moveH, moveV, 0);
transform.Translate (movement.normalized * moveSpeed * Time.deltaTime);
if(movement != Vector3.zero)
{
float angle = $$anonymous$$athf.Atan2 (moveV, moveH) * $$anonymous$$athf.Rad2Deg;
Quaternion rotation = Quaternion.AngleAxis (angle, Vector3.forward);
theRed.transform.rotation = Quaternion.Slerp (theRed.transform.rotation, rotation, Time.deltaTime * 5f);
}
}
}
Answer by FortisVenaliter · Apr 13, 2017 at 04:43 PM
Well first, get rid of the slerps. And since you're only editing one component of the rotation, I would store it as a float instead of a Vector3.
What you want to do is manually change the rotation value. If you have two variables, CurrentRotation and TargetRotation, you can do something like this:
float rotDiff = (TargetRotation-CurrentRotation);
while(rotDiff < -180)
rotDiff += 360;
while(rotDiff > 180)
rotDiff -= 360;
CurrentRotation += rotDiff * Time.deltaTime;
transform.rotation = Quaternion.Euler(0,0,CurrentRotation);
That will ensure it's always going in the shortest direction, and it allows you to track the rotation more easily.
If you store a float representing an angle as opposed to storing a Quaternion, you can go back to using lerps if you like (although it doesn't look like he was using it correctly) using the handy $$anonymous$$athf.LerpAngle() function which does the right thing when the angles wrap around 360/0. https://docs.unity3d.com/ScriptReference/$$anonymous$$athf.LerpAngle.html