四元数lerp来回

时间:2016-09-09 12:45:29

标签: c# unity3d

我想沿着Z轴前后lerp返回相同的量以避免旋转(因为我的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

使用Quaternions编辑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; }

import UIKit

class CustomSlider: UISlider {

/*
// Only override draw() if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
    // Drawing code
}
*/
// Increase slider height
   override func trackRect(forBounds bounds: CGRect) -> CGRect {
    let customBounds: CGRect = CGRect(origin: bounds.origin, size: CGSize(width: bounds.size.width, height: 5.0))
    return customBounds
}



override func thumbRect(forBounds bounds: CGRect, trackRect rect: CGRect, value: Float) -> CGRect {
    return super.thumbRect(
        forBounds: bounds, trackRect: rect, value: value)


}

// Increase Thumb hot spot clickable area
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
    var bounds: CGRect = self.bounds
    bounds = bounds.insetBy(dx: -10, dy: -10);
    return bounds.contains(point);

}

override func awakeFromNib() {
    // Configure Volume slider
    let thumbImageNormal = UIImage.init(named:"thumb")
    self.setThumbImage(thumbImageNormal, for: .normal)

    super.awakeFromNib()
}

}

2 个答案:

答案 0 :(得分:0)

您应该计算目标四元数,然后使用Quaternion.Slerp插入随机四元数并返回。而不是使用角度,您应该计算目标四元数。

答案 1 :(得分:0)

对于看到这个的人,我找到了解决方案。

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;
    }

}

解决方法是在Quaternion.Lerp中连续使用loop,并在循环完成后设置状态 。这样就完成了我想做的事。