我對 Unity 還很陌生,在瀏覽了關于通過幀旋轉的執行緒后,我設法找到了代碼來幫助我獲得我想要的游戲外觀,這是運動的代碼:
public class Movement : MonoBehaviour
{
IEnumerator RotateOctagon(Vector3 byAngles, float inTime)
{
var fromAngle = transform.rotation;
var toAngle = Quaternion.Euler(transform.eulerAngles byAngles);
for(var t = 0f; t <= 1; t = Time.deltaTime / inTime)
{
transform.rotation = Quaternion.Lerp(fromAngle, toAngle, t);
yield return null;
}
transform.rotation = toAngle;
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown("left"))
{
StartCoroutine(RotateOctagon(Vector3.forward * 45, 0.1f));
}
if (Input.GetKeyDown("right"))
{
StartCoroutine(RotateOctagon(Vector3.forward * -45, 0.1f));
}
if (Input.GetKeyDown("up"))
{
StartCoroutine(RotateOctagon(Vector3.forward * 180, 0.1f));
}
}
}
它會產生所需的結果 - 將八角形放在下一邊,假設您等到旋轉完成......

但是當您在影片中間按向左或向右時會出現問題,其中八角形錯誤地以點或奇怪的角度(不是 45 度的倍數)結束...

我的猜測是,如果八角形位于向右旋轉的協程的中間,比如說 30 度,任何直接按下的按鍵現在都會從那個角度旋轉,最終變成 30 - 45 一個不需要的角度。
I considered calculating the offset of the angle to the lower/higher 45 degree angle multiple, but I feel like there's a more correct approach and something I'm missing about coroutines that would help this.
Any help on how to get the octagon to rotate properly under the condition that multiple keys are pressed would be greatly appreciated.
Desired behavior: Say the current z axis is 0. After right is pressed and in the middle of rotating, left is pressed at 30 degrees. The octagon should rotate back to z=0
uj5u.com熱心網友回復:
為了在前一個例程完成之前不允許新例程,只需引入一個 bool 標志
private bool isRotating;
IEnumerator RotateOctagon(Vector3 byAngles, float inTime)
{
if(isRotating) yield break;
isRotating = true;
var fromAngle = transform.rotation;
var toAngle = Quaternion.Euler(transform.eulerAngles byAngles);
for(var t = 0f; t <= 1; t = Time.deltaTime / inTime)
{
transform.rotation = Quaternion.Lerp(fromAngle, toAngle, t);
yield return null;
}
transform.rotation = toAngle;
isRotating = false;
}
這樣您的輸入基本上會被忽略,直到上一個例程完成。
為了提高效率,您還可以添加
void Update()
{
if(isRotating) return;
...
}
或者沒有額外標志的“花哨”替代方案:使Start自己成為協程并執行
IEnumerator Start ()
{
while(true)
{
if (Input.GetKeyDown("left"))
{
// This now rotates and waits at the same time until the rotation is finished
yield return RotateOctagon(Vector3.forward * 45, 0.1f));
}
else if (Input.GetKeyDown("right"))
{
yield return RotateOctagon(Vector3.forward * -45, 0.1f));
}
else if (Input.GetKeyDown("up"))
{
yield return RotateOctagon(Vector3.forward * 180, 0.1f));
}
else
{
// If none of the previous is true wait at least one frame
yield return null;
}
}
}
或者,因為現在我們知道您想要中斷當前的旋轉并開始一個新的旋轉將它存盤在一個欄位中
private float rotation;
void Awake()
{
rotation = transform.localEulerAngles.z;
}
void Update()
{
if (Input.GetKeyDown("left"))
{
RotateAbout (45);
}
if (Input.GetKeyDown("right"))
{
RotateAbout (-45);
}
if (Input.GetKeyDown("up"))
{
RotateAbout (180);
}
}
private void RotateAbout(float angle)
{
StopAllCoroutines ();
rotation = angle;
StartCoroutine(RotateOctagon(rotation, 0.1f));
}
然后寧愿做
IEnumerator RotateOctagon(float toAngle, float inTime)
{
var fromRotation = transform.localRotation;
var toRotation = Quaternion.Euler(Vector3.forward * toAngle);
for(var t = 0f; t <= 1; t = Time.deltaTime / inTime)
{
transform.localRotation = Quaternion.Lerp(fromRotation, toRotation, t);
yield return null;
}
transform.localRotation = toRotation;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/341577.html
上一篇:C#-將JSON反序列化為物件,然后運行??foreach回圈添加到串列視圖中
下一篇:制作Type物件副本的簡單方法
