- Home /
Transform rotation and position on key input: rotation only working the first time
Hi,
I want to rotate and move a game object to a set position and rotation. The transform.position is working fine, but the rotation only works the first time I press the q and w key, but after that it doesn't rotate the object to the correct position.
I just can't work out what I'm doing wrong - I thought maybe I wasn't resetting a value correctly, but I can't see what I'm missing.
So I want the object to rotate to 9 degrees on the x axis every time q is pressed, and 45 degrees on the x axis when w is pressed.
Does anyone have any ideas on what I'm doing wrong?
Best, Laurien
Edit: updated script
using UnityEngine;
using System.Collections;
public class MovementRotationCoroutine : MonoBehaviour {
public GameObject cameraMain;
private float degree;
private float angle;
void Update () {
if (Input.GetKeyDown("q"))
{
degree = 9f;
StartCoroutine ( MoveToPositionPersp (new Vector3(0,0.5f,-5.5f), 2f, 2f));
}
if (Input.GetKeyDown("w"))
{
degree = 45f;
StartCoroutine ( MoveToPositionOrtho (new Vector3(0,5.5f,0), 2f, 2f));
}
}
public IEnumerator MoveToPositionOrtho(Vector3 position, float timeToMove, float waitTime)
{
yield return new WaitForSeconds(waitTime);
var currentPos = transform.position;
var currentPosRotate = transform.rotation;
var t = 0f;
while(t < 1)
{
t += Time.deltaTime / timeToMove;
transform.position = Vector3.Lerp(currentPos, position, t);
angle = Mathf.LerpAngle(transform.rotation.x, degree, t);
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(degree, 0, 0), t);
yield return null;
}
}
public IEnumerator MoveToPositionPersp(Vector3 position, float timeToMove, float waitTime)
{
yield return new WaitForSeconds(waitTime);
var currentPos = transform.position;
var currentPosRotate = transform.rotation;
var t = 0f;
while(t < 1)
{
t += Time.deltaTime / timeToMove;
transform.position = Vector3.Lerp(currentPos, position, t);
angle = Mathf.LerpAngle(transform.rotation.x, degree, t);
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(degree, 0, 0), t);
yield return null;
}
}
}
im not sure but maybe
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(degree, 0, 0), Time.deltaTime);
should be
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(degree, 0, 0), t);
Thanks - you're right, I think Time.deltaTime should have been t, the speed of rotation works as expected now.
But - it's still not rotating correctly, it seems to be doubling the value I want it to rotate to each time.
If the camera starts at 9 degrees, and I press 'w' first it rotates to 45 degrees correctly, if I press 'q' after this it rotates back to 9 degrees correctly.
But after that if I alternate between pressing 'w' and 'q' the values go:
45 9 54 18 63 27 etc.
I've updated the script with t ins$$anonymous$$d of time.deltaTime, and also changed this line:
if (Input.Get$$anonymous$$eyDown("q"))
{
degree += 36f;
StartCoroutine ( $$anonymous$$oveToPositionPersp (new Vector3(0,0.5f,-5.5f), 2f, 2f));
}
to this:
if (Input.Get$$anonymous$$eyDown("w"))
{
degree += 45f;
StartCoroutine ( $$anonymous$$oveToPositionOrtho (new Vector3(0,5.5f,0), 2f, 2f));
}
}
But I'm not sure how to change it so it rotates to a set value each time a key is pressed. (So it always rotates to 9 degrees when 'q' is pressed, and always rotates to 45 degrees when 'w' is pressed).
You mean like if you press w it always rotates to the nearest multiple of 45 and on q it rotates to the multiple of 9?
Oh sorry - no I didn't say that very clearly. I want the rotation of the object to switch between 45 degrees and 9 degrees. (Like a clamped $$anonymous$$ and max rotation). So when w is pressed: the object rotates to 45 degrees. (so in the hierarchy the rotation of the object would always read 45, 0, 0.) When q is pressed the object rotates back to 9 degrees. (so in the hierarchy the rotation of the object would always read 9, 0, 0.)
(at the moment it seems to be rotating in multiples but this isn't what I want)
change the additive nature of:
if (Input.Get$$anonymous$$eyDown("q"))
{
degree -= 36f;
StartCoroutine ( $$anonymous$$oveToPositionPersp (new Vector3(0,0.5f,-5.5f), 2f, 2f));
}
if (Input.Get$$anonymous$$eyDown("w"))
{
degree += 45f;
StartCoroutine ( $$anonymous$$oveToPositionOrtho (new Vector3(0,5.5f,0), 2f, 2f));
}
to an absolute:
if (Input.Get$$anonymous$$eyDown("q"))
{
degree = 9f;
StartCoroutine ( $$anonymous$$oveToPositionPersp (new Vector3(0,0.5f,-5.5f), 2f, 2f));
}
if (Input.Get$$anonymous$$eyDown("w"))
{
degree = 45f;
StartCoroutine ( $$anonymous$$oveToPositionOrtho (new Vector3(0,5.5f,0), 2f, 2f));
}
Ohh that's really great thank you!! I misunderstood how that worked, just looked that up now!
I've just updated the script now! (If you convert your comment to an answer I can tick it as answered).
So it now rotates correctly - but I was wondering if you knew why this happened?
If I press the 'w' key while the game object is still moving towards the correct rotation and position for 'q', then the rotation switches immediately to the 'w' position, but the translation finishes moving to 'q' and before moving to 'w'.
Ideally I'd want it to pause at whatever position it was and then start rotating and moving back to 'w' (and vice versa).
Do you know how I could go about changing this?
Answer by ninja_gear · Jun 19, 2016 at 06:35 PM
Save your coroutines in an ienumerator. When calling one or the other, stop the coroutines, then start up the new one:
IEnumerator _rotating;
If (_rotating != null) StopCoroutine(_rotating); StartCoroutine(_rotating = MoveToPositionPers('args'));
That's great - it's working perfectly now. Thanks so much!!
Answer by jarjarb · Feb 21, 2021 at 01:18 PM
may you help me with my code?
what I want to do is make it make my rotations get stored in a quaternion and then change the quaternion to look up and down when the left and right arrow keys are pressed. However I am fairly new to quaternions and unity in general so I have no Idea how to do this.
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class look : MonoBehaviour {
[SerializeField]
KeyCode up;
[SerializeField]
KeyCode down;
// Update is called once per frame
void Update()
{
if (Input.GetKey(up))
{
transform.Rotate(-2f, 0f, 0f);
}
if (Input.GetKey(down))
{
transform.Rotate(2f, 0f, 0f);
}
}
}
please help me with integrating the quaternions into my code.
all I would like it to do is clamp my rotations to between -90 and 90 so I am not making it so that when you look down too far you won't look in 180 degrees.