如何统一减慢旋转物体

how to slow a rotating object in unity

我正在尝试写一个命运之轮类型的东西。我希望轮子旋转一段时间,然后在随机位置缓慢停止。

我目前所做的一切都有效,但停止太突然了。在某处使用 Slerp 可能会解决问题。但是我在确保轮子只顺时针旋转方面也遇到了麻烦!

 public class WheelOptions : MonoBehaviour
 {
     [SerializeField] int spinDuration = 5;
     [SerializeField] int seedValue = 5;
     [SerializeField] SectionColors[] sectionColors;

     Vector3 targetPosition;

     bool isSpinning = false;
     bool hasSpun = false;
     int currentSpin = 0;

     void Start()
     {
         targetPosition = new Vector3(Random.Range(-5, 5), 0f, Random.Range(-5, 5));
     }

     public void SpinWheel()
     {

         isSpinning = true;
         hasSpun = false;

         targetPosition = new Vector3(Random.Range(-5, 5), 0f, Random.Range(-5, 5));

         StartCoroutine( StopTimer() );
     }

     void Update()
     {
         transform.position = new Vector3(0f, 0, 0f);
    
         if (isSpinning == true)
         {
             if (currentSpin < 360)
             {
                 currentSpin++;
             }
             else currentSpin = 0;

             this.transform.rotation = Quaternion.Euler(0, currentSpin, 0);
         }
         else if(hasSpun == true)
         {
             Quaternion rotation = Quaternion.LookRotation(targetPosition - transform.position, transform.TransformDirection(Vector3.forward)); 
             transform.rotation = new Quaternion(0, rotation.y, 0, rotation.w);
         }
     }

     IEnumerator StopTimer()
     {
         yield return new WaitForSeconds(spinDuration);

         isSpinning = false;
         hasSpun = true;
     }

 }
public float speed = 1.0f;
public float forceRemain = 1.0f;
public bool isSpin = false;

private Quanternion lastRot;
private float rm = forceRemain;
void Update(){
 if(isSpin){
  this.transform.rotation = new Quanternion(o, 
  lastRot.y + (speed * Time.DeltaTime), 0, // rotate right while isSpin
  lastRot.w);
 }
 else{
  if(rm > 0){
   rm -= Time.DeltaTime; //slowin down remain force
  }
  else{
   rm = forceRemain; //reset remain force
  }
 }
}

抱歉我的代码不太准确

你的旋转想法让它无法顺利停止。将 isSpinning 设置为 false 将完全阻止平滑。您需要某种公式来根据时间计算所需的旋转。在某种程度上,即使计算机的 fps 很低,微调器仍会降落到相同的确定目的地。

此外,在 5x5 正方形内获得随机位置的逻辑给出了对角落的不均匀分布。旋转器会更频繁地停在角落。


我创建了一个 Rotator 脚本供您借鉴。 targetSpin 是微调器旋转的总度数。 spinDuration 是旋转的秒数。剩下的就是数学和物理了。

public class Rotater : MonoBehaviour
{
    public float spinDuration = 3f;
    public float targetSpin = 3600f;
    float initSpin = 0f;
    float initSpeed = 0f;
    float acceleration = 0f;
    float startRotTime = 0f;

    private void CalcInitSpeedingConditions()
    {
        // Here we assume constant acceleration, and ending speed must be 0.
        initSpeed = 2 * targetSpin / spinDuration;
        acceleration = -initSpeed / spinDuration;
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            // targetSpin = Random.Range(1000f, 1360f);  # Use this to spin random on each press
            CalcInitSpeedingConditions();
            startRotTime = Time.time;
            initSpin = transform.localEulerAngles.y;
            StartCoroutine(Rotate());
        }
    }

    // This is fundamental physics formula
    private float GetRotationByTime(float t) => initSpeed * t + acceleration * t * t / 2;

    IEnumerator Rotate()
    {
        float t = Time.time - startRotTime;
        while (t < spinDuration) 
        {
            t = Time.time - startRotTime;
            GetRotationByTime(t);
            transform.localEulerAngles = Vector3.up * (initSpin + GetRotationByTime(t) % 360);
            yield return null;
        }
        transform.localEulerAngles = Vector3.up * (initSpin + GetRotationByTime(t) % 360);
    }
}