[英]Quaternion lerp back and forth
我想lerp
沿Z軸來回等量避免紡(如我的sprite
是不是圓形的)。 為此,我計划將forward angle
隨機化,將其存儲起來, lerp
它,然后lerp
相同的角度。 但是,這會產生一些怪異的彈出聲,因為向后旋轉開始時的起始角度將不相同,而是相同。 當我調用它時,我給它同時進行插值的時間。 一些代碼:
IEnumerator LerpQuat(QuatLerpInput rotThis, float time, float leftBoundary, float rightBoundary)
{
/*
* we want to rotate forward, then backward the same amount
* to avoid spinning. we store the given value to both of these.
*/
Transform stuffToRot = rotThis.godRayGO.transform;
float lastTime = Time.realtimeSinceStartup;
float timer = 0.0f;
switch (rotThis.rotState)
{
case (QuatLerpInput.RotationStates.rotAway):
rotThis.deltaRot = Random.Range(leftBoundary, rightBoundary);
while (timer < time)
{
stuffToRot.rotation = Quaternion.Euler(stuffToRot.rotation.x, stuffToRot.rotation.y,
Mathf.LerpAngle(rotThis.idleRot, rotThis.idleRot + rotThis.deltaRot, timer / time));
timer += (Time.realtimeSinceStartup - lastTime);
lastTime = Time.realtimeSinceStartup;
yield return null;
}
rotThis.rotState = QuatLerpInput.RotationStates.setBack;
break;
case (QuatLerpInput.RotationStates.setBack):
while (timer < time)
{
stuffToRot.rotation = Quaternion.Euler(stuffToRot.rotation.x, stuffToRot.rotation.y,
Mathf.LerpAngle(rotThis.idleRot + rotThis.deltaRot, rotThis.idleRot, timer / time));
timer += (Time.realtimeSinceStartup - lastTime);
lastTime = Time.realtimeSinceStartup;
yield return null;
}
rotThis.rotState = QuatLerpInput.RotationStates.rotAway;
break;
}
}
public class QuatLerpInput
{
public GameObject godRayGO;
public float deltaRot;
public float idleRot;
public enum RotationStates
{
rotAway, setBack
}
public RotationStates rotState = RotationStates.rotAway;
public QuatLerpInput(GameObject godRayGO)
{
this.godRayGO = godRayGO;
deltaRot = godRayGO.transform.rotation.z;
idleRot = godRayGO.transform.rotation.z;
}
}
使用四元數編輯的switch
:
switch (rotThis.rotState)
{
case (QuatLerpInput.RotationStates.rotAway):
rotThis.deltaRot = Random.Range(leftBoundary, rightBoundary);
Quaternion destination = new Quaternion(rotThis.idleQuat.x, rotThis.idleQuat.y, rotThis.idleQuat.z + rotThis.deltaRot, 1.0f);
rotThis.deltaQuat = destination;
while (timer < time)
{
stuffToRot.rotation = Quaternion.Slerp(rotThis.idleQuat, rotThis.deltaQuat, timer/time);
//stuffToRot.rotation = Quaternion.Euler(stuffToRot.rotation.x, stuffToRot.rotation.y,
// Mathf.LerpAngle(rotThis.idleRot, rotThis.idleRot + rotThis.deltaRot, timer / time));
timer += (Time.realtimeSinceStartup - lastTime);
lastTime = Time.realtimeSinceStartup;
yield return null;
}
rotThis.rotState = QuatLerpInput.RotationStates.setBack;
break;
case (QuatLerpInput.RotationStates.setBack):
while (timer < time)
{
stuffToRot.rotation = Quaternion.Slerp(rotThis.deltaQuat, rotThis.idleQuat, timer / time);
//stuffToRot.rotation = Quaternion.Euler(stuffToRot.rotation.x, stuffToRot.rotation.y,
// Mathf.LerpAngle(rotThis.idleRot + rotThis.deltaRot, rotThis.idleRot, timer / time));
timer += (Time.realtimeSinceStartup - lastTime);
lastTime = Time.realtimeSinceStartup;
yield return null;
}
rotThis.rotState = QuatLerpInput.RotationStates.rotAway;
break;
}
而不是約束角度,您應該計算目標四元數並使用Quaternion.Slerp
插值到隨機四元數並返回。
對於任何看到這一點的人,我都找到了解決方案。
void LerpQuat(QuatLerpInput rotThis, float time, float leftBoundary, float rightBoundary)
{
/*
* we want to rotate forward, then backward the same amount
* to avoid spinning. we store the given value to both of these.
*/
Transform stuffToRot = rotThis.godRayGO.transform;
float lastTime = Time.realtimeSinceStartup;
float timer = 0.0f;
switch (rotThis.rotState)
{
case (QuatLerpInput.RotationStates.rotAway):
rotThis.deltaRot = Random.Range(leftBoundary, rightBoundary);
Quaternion destination = new Quaternion(rotThis.idleQuat.x, rotThis.idleQuat.y, rotThis.deltaRot, 1.0f);
rotThis.deltaQuat = destination;
rotThis.deltaEulerAngle = Vector3.forward * rotThis.deltaRot;
StartCoroutine(RotateMe(rotThis, rotThis.idleQuat, rotThis.deltaEulerAngle, initiateAlphaSwap));
break;
case (QuatLerpInput.RotationStates.setBack):
StartCoroutine(RotateMe(rotThis, rotThis.deltaQuat,-1.0f * rotThis.deltaEulerAngle, initiateAlphaSwap));
break;
}
}
IEnumerator RotateMe(QuatLerpInput whatToRotate,Quaternion fromWhere,Vector3 byAngles, float inTime)
{
Quaternion fromAngle = fromWhere;
Quaternion toAngle = Quaternion.Euler(whatToRotate.godRayGO.transform.eulerAngles + byAngles);
toAngle = new Quaternion(toAngle.x, toAngle.y, toAngle.z, 1.0f);
if(whatToRotate.rotState == QuatLerpInput.RotationStates.setBack)
{
fromAngle = new Quaternion(whatToRotate.RotEndPos.x, whatToRotate.RotEndPos.y, whatToRotate.RotEndPos.z, 1.0f);
toAngle = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
}
for (float t = 0.0f; t < 1.0f; t += Time.deltaTime / inTime)
{
whatToRotate.godRayGO.transform.rotation = Quaternion.Lerp(fromAngle, toAngle, t);
yield return null;
}
if(whatToRotate.rotState == QuatLerpInput.RotationStates.rotAway)
{
whatToRotate.rotState = QuatLerpInput.RotationStates.setBack;
whatToRotate.RotEndPos = new Vector3(toAngle.x, toAngle.y, toAngle.z);
}
else
{
whatToRotate.rotState = QuatLerpInput.RotationStates.rotAway;
}
}
解決方法是在loop
連續使用Quaternion.Lerp
並在循環結束后設置狀態。 這樣就可以實現我想要的功能。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.