来回旋转GameObject
我想在Y轴上在90,-90之间来回旋转对象。 问题是我可以在-90中设置编辑器中的对象,但是当我运行项目时-90突然变为270.无论如何这里是我正在使用的代码:
void Update() { if (transform.eulerAngles.y >= 270) { transform.Rotate(Vector3.up * speed * Time.deltaTime); } else if (transform.eulerAngles.y <= 90) { transform.Rotate(Vector3.up * -speed * Time.deltaTime); } }
它总是在360度左右卡在中间。 救命?
就像来回移动 GameObject一样,您可以使用Mathf.PingPong
来回旋转Mathf.PingPong
。 这就是它的用途。 它将返回0到1之间的值。 您可以将该值传递给Vector3.Lerp
并生成执行旋转所需的eulerAngle 。
这也可以使用协程来完成,但如果您不需要知道何时到达目的地,则应使用Mathf.PingPong
。 如果您想知道何时到达旋转目的地,则应使用协程。
public float speed = 0.36f; Vector3 pointA; Vector3 pointB; void Start() { //Get current position then add 90 to its Y axis pointA = transform.eulerAngles + new Vector3(0f, 90f, 0f); //Get current position then substract -90 to its Y axis pointB = transform.eulerAngles + new Vector3(0f, -90f, 0f); } void Update() { //PingPong between 0 and 1 float time = Mathf.PingPong(Time.time * speed, 1); transform.eulerAngles = Vector3.Lerp(pointA, pointB, time); }
编辑:
使用coroutine方法可以确定每次旋转的结束。
public GameObject objectToRotate; public float speed = 0.36f; Vector3 pointA; Vector3 pointB; void Start() { //Get current position then add 90 to its Y axis pointA = transform.eulerAngles + new Vector3(0f, 90f, 0f); //Get current position then substract -90 to its Y axis pointB = transform.eulerAngles + new Vector3(0f, -90f, 0f); objectToRotate = this.gameObject; StartCoroutine(rotate()); } IEnumerator rotate() { while (true) { //Rotate 90 yield return rotateObject(objectToRotate, pointA, 3f); //Rotate -90 yield return rotateObject(objectToRotate, pointB, 3f); //Wait? //yield return new WaitForSeconds(3); } } bool rotating = false; IEnumerator rotateObject(GameObject gameObjectToMove, Vector3 eulerAngles, float duration) { if (rotating) { yield break; } rotating = true; Vector3 newRot = gameObjectToMove.transform.eulerAngles + eulerAngles; Vector3 currentRot = gameObjectToMove.transform.eulerAngles; float counter = 0; while (counter < duration) { counter += Time.deltaTime; gameObjectToMove.transform.eulerAngles = Vector3.Lerp(currentRot, newRot, counter / duration); yield return null; } rotating = false; }
首先,你应该始终确保角度保持在0
到359
之间,这意味着0 == 360
:
float angle = transform.eulerAngles.y % 360.00f;
之后,您可以检查它是否在您的最小值和最大值之间 :
if ( angle >= 270.00f && angle <= 90.00f ) { // do your logic here ... }
您的代码的另一个问题是它会卡在350
到10
度之间。 为了更详细地解释这一点,我们假设你的速度是10
, Time.deltaTime
也是1
,起始角度是300
,现在帧步骤:
Frame | Angle | Condition ----- | ----- | :-----------: 1 | 300 | angle >= 270 2 | 310 | angle >= 270 3 | 320 | angle >= 270 6 | 350 | angle >= 270 7 | 360 | angle >= 270 8 | 10 | angle <= 90 9 | 0 | angle <= 90 10 | 350 | angle >= 270
......这将永远存在。
要处理这个问题,你必须根据用户输入制作一些条件,或者如果你想让你的相机在这两个角度之间“反弹”,那么你可以尝试这样的事情:
// make private field in that object : float currentlyRotated = 0; bool shouldAdd = true; void Update() { var d = Vector3.up * (shouldAdd ? speed : -speed) * Time.deltaTime; var angle = transform.eulerAngles.y + (shouldAdd ? speed : -speed); angle %= 360.00f; transform.Rotate(d); if ( angle > 90 && angle < 270 ) { shouldAdd = !shouldAdd; } }