找到旋转的差异,作为随时间统一的平均值 c#

Finding the difference in rotation, as an average over time unity c#

我有一个玩家可以旋转的船轮。我目前记录角度变化,它被添加到一个总角度。然后我可以计算出船轮转动了多少次。这一切都很好。

void Update()
        {
            //Record Amount of Wheel Turns
            currentAngle = wheelRectTransform.transform.rotation.eulerAngles.z;
            angleChange = Mathf.DeltaAngle(currentAngle, previousAngle);

            if ((Mathf.Abs(angle + angleChange) / 360) <=   wheelTurnsUntilRudderAtMaxAngle)
            {            
               angle += angleChange;               
            } 

            totalWheelTurns = angle / 360;
            shipStats.RudderAngle = totalWheelTurns / wheelTurnsUntilRudderAtMaxAngle;

            previousAngle = currentAngle;
        }

不过,我也想记录一下平均角度随时间的变化。然后我就可以准确地知道轮子是向左还是向右旋转。

我试过像这样简单的东西

if (angleChange < 0)
{
     // Going Left
}
else if (angleChange > 0)
{
     // Going Right
} else
{
    // Not moving
}

然而在实践中,如果玩家旋转轮子的速度非常非常慢,则偶尔帧上的角度差为 0 并记录为 'not moving'。

我相信解决方案是找到短时间内的平均角度变化,因此我尝试将角度随时间 Lerp 到 0。

newAngleDifference = Mathf.Lerp(angleChange, 0, Time.deltaTime * 0.2f);

这没有用,它给我的反馈和我刚刚使用的 'angleChange' 一样,无论如何都可以是 0。

谢谢!

吉姆

您不需要平均任何东西来检测车轮的方向。只需使用旧变量和新变量来查找车轮的行驶方向。

 void Start()
 {
        StartCoroutine(wheelDIRCalculator(_wheelTransform));
 }


bool continueWheelCalculation = false;

 IEnumerator wheelDIRCalculator(Transform wheelTransform)
 {
     yield return null;

     continueWheelCalculation = true;

     float oldZAngle = 0;
     float newZAngle = 0;
     bool isIdle = false;

     oldZAngle = Mathf.Abs(wheelTransform.rotation.eulerAngles.z);


     while (continueWheelCalculation)
     {

         //Get new rotation
         newZAngle = Mathf.Abs(wheelTransform.rotation.eulerAngles.z);

         if (oldZAngle < newZAngle)
         {
             isIdle = false;
             oldZAngle = newZAngle;
             Debug.Log("Left");

             //Do something 

         }
         else if (oldZAngle > newZAngle)
         {
             isIdle = false;
             oldZAngle = newZAngle;
             Debug.Log("Right");

             //Do something 

         }
         else if (!isIdle)
         {
             isIdle = true;
             oldZAngle = newZAngle;
             Debug.Log("Idle");

             //Do something 

         }


         yield return null;
     }
 }

 void stopWheelDIRCalculator()
 {
    continueWheelCalculation = false;
 }

最后我用了Lerp求平均值。

    public enum WheelDirection { Left, Right, Still }

    [Header("Average Wheel Direction")]
    public float lerpTime = 0.5f; // How many seconds average over
    private WheelDirection wheelDirection; 
    private float wheelDeltaX;
    private float wheelDirectionInterpolated;
    private float currentLerpTime;

 void Update()
    {
        // Get DeltaX of objects rotation 
        // I'm interested in the Z axis, but you could change this to x/y           
        float currentAngle = transform.rotation.eulerAngles.z;
        wheelDeltaX = (currentAngle - previousAngle);

        // Reduce the Lerp percentage
        currentLerpTime += Time.deltaTime;
        if (currentLerpTime > lerpTime)
        {
            currentLerpTime = lerpTime;
        }
        float perc = currentLerpTime / lerpTime;

        // Lerp!
        wheelDirectionInterpolated = (Mathf.Lerp(wheelDirectionInterpolated, wheelDeltaX, perc));

        // Wheel has finished rotating, so reset the Lerp
        if (wheelDirectionInterpolated == 0) currentLerpTime = 0;

        // Store Direction in an Enum
        if (wheelDirectionInterpolated > 0) wheelDirection = WheelDirection.Left;
        if (wheelDirectionInterpolated < 0) wheelDirection = WheelDirection.Right;
        if (wheelDirectionInterpolated == 0) wheelDirection = WheelDirection.Still;

        //This should always be at the end
        previousAngle = currentAngle;
    }