在协程中使用 Quaternion.RotateTowards() 旋转对象?
Rotate an object using Quaternion.RotateTowards() inside a Coroutine?
我正在尝试使用 Quaternion.RotateTowards()
在 Coroutine
中旋转对象。但它不像 Update()
那样顺畅地旋转。
相反,它捕捉到目标旋转。
怎么了?这是我的脚本:
public class SpinWheelScript : MonoBehaviour {
public GameObject[] rewards;
public GameObject[] pointerDir;
public GameObject[] ringDir;
public GameObject pointer;
public GameObject ring;
private Quaternion pointerTargetRotation;
private Quaternion ringTargetRotation;
private bool spinIsEnabled = true;
private bool isSpinning = false;
private float pSpeed;
private float rSpeed;
private float pointerRotateFloat;
private float ringRotateFloat;
private int rewardEnabler = 0;
private int randomReward;
private int pRandomDir;
private int rRandomDir;
private int plastRandomDir = 0;
private int rlastRandomDir = 0;
private void Update()
{
if (spinIsEnabled == false)
{
// Do Nothing
}
else if (spinIsEnabled == true && isSpinning == false)
{
// Select reward
if (rewardEnabler == 0)
{
RewardSelector();
rewardEnabler = 1;
}
StartCoroutine(Spin());
}
}
IEnumerator Spin()
{
isSpinning = true;
pSpeed = 0;
rSpeed = 0;
// Speed increasing spin for 5 seconds
PointerRandomDirection();
RingRandomDirection();
while (true)
{
pointerRotateFloat = (((pRandomDir + 1) * 60) - 30) - pointer.transform.rotation.z;
ringRotateFloat = (((rRandomDir + 1) * 60) - 30) - ring.transform.rotation.z;
pSpeed = (pointerRotateFloat / 2);
rSpeed = (ringRotateFloat / 2);
pointerTargetRotation = Quaternion.Euler(new Vector3(0, 0, pointerRotateFloat));
pointer.transform.rotation = Quaternion.RotateTowards(pointer.transform.rotation, pointerTargetRotation, pSpeed * Time.deltaTime);
ringTargetRotation = Quaternion.Euler(new Vector3(0, 0, ringRotateFloat));
ring.transform.rotation = Quaternion.RotateTowards(ring.transform.rotation, ringTargetRotation, rSpeed * Time.deltaTime);
if ((pointer.transform.rotation == pointerTargetRotation) && (ring.transform.rotation == ringTargetRotation))
break;
}
yield return new WaitForSeconds(1);
Debug.Log("Done!");
}
private int RewardSelector()
{
randomReward = Random.Range(0, rewards.Length);
return randomReward;
}
private int PointerRandomDirection()
{
int pRandomDir = plastRandomDir;
if (pointerDir.Length <= 1)
return 0;
while (pRandomDir == plastRandomDir)
{
pRandomDir = Random.Range(0, pointerDir.Length);
}
plastRandomDir = pRandomDir;
return pRandomDir;
}
private int RingRandomDirection()
{
int rRandomDir = rlastRandomDir;
if (ringDir.Length <= 1)
return 0;
while (rRandomDir == rlastRandomDir)
{
rRandomDir = Random.Range(0, ringDir.Length);
}
rlastRandomDir = rRandomDir;
return rRandomDir;
}
}
您没有在协程内生成等待指令。
在 while (true)
循环的内部(可能在末尾),简单地写一些类似 yield return null;
的东西。这将告诉协程将下一行代码的执行延迟到下一帧。
我正在尝试使用 Quaternion.RotateTowards()
在 Coroutine
中旋转对象。但它不像 Update()
那样顺畅地旋转。
相反,它捕捉到目标旋转。
怎么了?这是我的脚本:
public class SpinWheelScript : MonoBehaviour {
public GameObject[] rewards;
public GameObject[] pointerDir;
public GameObject[] ringDir;
public GameObject pointer;
public GameObject ring;
private Quaternion pointerTargetRotation;
private Quaternion ringTargetRotation;
private bool spinIsEnabled = true;
private bool isSpinning = false;
private float pSpeed;
private float rSpeed;
private float pointerRotateFloat;
private float ringRotateFloat;
private int rewardEnabler = 0;
private int randomReward;
private int pRandomDir;
private int rRandomDir;
private int plastRandomDir = 0;
private int rlastRandomDir = 0;
private void Update()
{
if (spinIsEnabled == false)
{
// Do Nothing
}
else if (spinIsEnabled == true && isSpinning == false)
{
// Select reward
if (rewardEnabler == 0)
{
RewardSelector();
rewardEnabler = 1;
}
StartCoroutine(Spin());
}
}
IEnumerator Spin()
{
isSpinning = true;
pSpeed = 0;
rSpeed = 0;
// Speed increasing spin for 5 seconds
PointerRandomDirection();
RingRandomDirection();
while (true)
{
pointerRotateFloat = (((pRandomDir + 1) * 60) - 30) - pointer.transform.rotation.z;
ringRotateFloat = (((rRandomDir + 1) * 60) - 30) - ring.transform.rotation.z;
pSpeed = (pointerRotateFloat / 2);
rSpeed = (ringRotateFloat / 2);
pointerTargetRotation = Quaternion.Euler(new Vector3(0, 0, pointerRotateFloat));
pointer.transform.rotation = Quaternion.RotateTowards(pointer.transform.rotation, pointerTargetRotation, pSpeed * Time.deltaTime);
ringTargetRotation = Quaternion.Euler(new Vector3(0, 0, ringRotateFloat));
ring.transform.rotation = Quaternion.RotateTowards(ring.transform.rotation, ringTargetRotation, rSpeed * Time.deltaTime);
if ((pointer.transform.rotation == pointerTargetRotation) && (ring.transform.rotation == ringTargetRotation))
break;
}
yield return new WaitForSeconds(1);
Debug.Log("Done!");
}
private int RewardSelector()
{
randomReward = Random.Range(0, rewards.Length);
return randomReward;
}
private int PointerRandomDirection()
{
int pRandomDir = plastRandomDir;
if (pointerDir.Length <= 1)
return 0;
while (pRandomDir == plastRandomDir)
{
pRandomDir = Random.Range(0, pointerDir.Length);
}
plastRandomDir = pRandomDir;
return pRandomDir;
}
private int RingRandomDirection()
{
int rRandomDir = rlastRandomDir;
if (ringDir.Length <= 1)
return 0;
while (rRandomDir == rlastRandomDir)
{
rRandomDir = Random.Range(0, ringDir.Length);
}
rlastRandomDir = rRandomDir;
return rRandomDir;
}
}
您没有在协程内生成等待指令。
在 while (true)
循环的内部(可能在末尾),简单地写一些类似 yield return null;
的东西。这将告诉协程将下一行代码的执行延迟到下一帧。