- Home /
Rotate object without storing facing
Hello, I'm rather new at using Unity, so I apologize if this is trivial, but I haven't found a good solution for it online.
I've made a cube out of 6 planes, grouped them and added them to an empty game object with the location of the center of the cube and added my rotate script to it.
I want to move and rotate this cube 90 degrees in one of four direction when pressing a key (just press, not holding down). I've got the translation working great, however the rotation is giving me trouble. I've tried :
Quaternion toRotation = transform.rotation;
toRotation *= Quaternion.Euler(rotationToadd);
And then Quaternion.Slerp()
and it works well when moving only left to right or front to back, but when I move forward and then left the rotation is messed up.
What I would like to do is add or substract 90 degrees from the cube's rotation, no matter which way it's facing. E.g. add 90 degrees on Z axis => cube rotates =>new rotation is still (0,0,0).
Answer by Scribe · May 23, 2018 at 05:05 PM
Rather than using Quaternion.Euler
try Quaternion.AngleAxis
in this case the angle will always be +/-90 and you choose the axis to rotate around. To rotate horizontally that would be Vector3.up
for vertical it would be Vector3.right
.
Edit So I forgot an important bit! What makes the AngleAxis method a useful one is that we can transform the axis into local space which isn't so easily done using a Eulerian representation. In the context of your code this looks like:
Vector3 axis = ...;
Quaternion fromRotation = transform.rotation;
Vector3 localAxis = transform.InverseTransformDirection(axis);
Quaternion toRotation = transform.rotation * Quaternion.AngleAxis(rotationToadd, localAxis);
Hope that helps!
Thanks for your answer, that's definitely the method I need. However I'm unsure how to use it properly. This is what I have so far and the problem is still there. Quaternion fromRotation = transform.rotation; Quaternion toRotation = transform.rotation * Quaternion.AngleAxis(rotationToadd, axis);
float elapsed = 0.0f;
while (elapsed < duration)
{
transform.rotation = Quaternion.Slerp(fromRotation, toRotation, elapsed / duration);
elapsed += Time.deltaTime;
yield return null;
}
transform.rotation = toRotation;
Can you add the code you are using to find 'axis' please :)
Of course, thank you for taking an interest :) Here's all I've got:
void FixedUpdate()
{
if (Input.any$$anonymous$$eyDown && !moving && !rotating)
{
Vector3 movementVector = Vector3.zero;
if (Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.D))
{
movementVector = new Vector3(1, 0, 0);
StartCoroutine(Rotate(-90, Vector3.forward, .2f));
}
else
if (Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.A))
{
movementVector = new Vector3(-1, 0, 0);
StartCoroutine(Rotate(90, Vector3.forward, .2f));
}
else
if (Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.W))
{
movementVector = new Vector3(0, 0, 1);
StartCoroutine(Rotate(90, Vector3.right, .2f));
}
else
if (Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.S))
{
movementVector = new Vector3(0, 0, -1);
StartCoroutine(Rotate(-90, Vector3.right, .2f));
}
if (!movementVector.Equals(Vector3.zero))
{
startPosition = transform.position;
endPosition = startPosition + movementVector;
journeyLength = Vector3.Distance(startPosition, endPosition);
startTime = Time.time;
moving = true;
rotating = true;
}
}
if (moving)
{
float distCovered = (Time.time - startTime) * moveSpeed;
float fracJourney = distCovered / journeyLength;
transform.position = Vector3.Lerp(startPosition, endPosition, fracJourney);
if (transform.position.Equals(endPosition))
{
moving = false;
}
}
}
IEnumerator Rotate(float rotationToadd, Vector3 axis, float duration)
{
Quaternion fromRotation = transform.rotation;
Quaternion toRotation = transform.rotation * Quaternion.AngleAxis(rotationToadd, axis);
float elapsed = 0.0f;
while (elapsed < duration)
{
transform.rotation = Quaternion.Slerp(fromRotation, toRotation, elapsed / duration);
elapsed += Time.deltaTime;
yield return null;
}
transform.rotation = toRotation;
rotating = false;
}