Unity3d随着时间的推移在特定点周围旋转

时间:2016-05-13 14:08:36

标签: c# unity3d interpolation

我正在写一个功能,在一段时间内慢慢转动90度。到目前为止一切工作正常,我只需要弄清楚如何使它围绕一个点旋转而不是围绕变换中心旋转。

protected bool _isRotating = false;
public IEnumerator RotateWithEasing(GameHelper.Axis axis, Vector3 isolatedAxisPoint, float inTime)
{
    if(_isRotating)
    {
        yield break;
    }

    _isRotating = true;

    var degrees = this.GetDegreesFromAxis(axis);

    Quaternion fromAngle = transform.rotation;
    Quaternion toAngle = Quaternion.Euler(transform.eulerAngles + degrees);
    for (float t = 0f; t < 1f; t += Time.deltaTime / inTime)
    {
        transform.rotation = Quaternion.Lerp(fromAngle, toAngle, t);
        yield return null;
    }

    _isRotating = false;
}

任何人都可以帮我指出正确的方向,如何修改它以使其围绕指定的isolatedAxisPoint旋转?

2 个答案:

答案 0 :(得分:5)

这是一个实际的例子Unity补间,恰好在文本编辑器中显示另一个窗口!

如果你想旋转某些东西,只需在IEnumerator的循环中使用deltaTime,并调整 eulerAngles 或只需调用旋转。 (在Unity中不要出于任何原因使用四元数。)在本例中,我只调用Rotate。

这是Unity中非常基本的模式

以下是Unity中补间的基本模式。你将在Unity中完成这1000次!

  1. 计算结束时间
  2. 执行while循环直到达到该时间
  3. 每个框架,滑动(或其他)适当的分数。
  4. 请注意,当然是

     yield return null;
    

    在循环中,它意味着&#34;等到下一帧&#34;。

    (请注意,与任何补间一样,最后强制设置最终值是一种很好的做法,因此您知道它非常完美。请注意此示例中的I只需在循环结束时设置eulerAngles即可。)

    private IEnumerator _roll( Vector3 delta )
        {
        rollBegins.Invoke();
    
        Vector3 begin = transform.eulerAngles;
    
        float rollSecs = 2f; // speed of the roll
    
        float startTime = Time.time;
        float endTime = startTime+rollSecs;
    
        while (Time.time < endTime)
            {
            Vector3 d = delta * ( Time.deltaTime / rollSecs );
            transform.Rotate(d, Space.World );
            yield return null;
            }
    
        transform.eulerAngles = .. perfectly correct end values;
    
        busy = false;
    
        rollComplete.Invoke();
        }
    

    {注意,在那个实际的代码示例中,&#34; delta&#34;被理解为仅在一个轴上;不要担心这个,它只是使用协程的补间的一个例子。}

    注意 - 当然有&#34;两种方式&#34; 进入循环。你可以计算少量你应该移动那一帧。或者,您可以计算当时新职位应该是什么。它取决于你。许多程序员认为后者更合乎逻辑,如果是这样,就这样做。另请注意,您可以执行while循环直到某个时间过去,或者,您可以执行while循环直到到达目的地! (对浮动平等非常小心。)选择是你的。

    请注意,您经常使用 Lerp 或更好的 SmoothStep 来补充此类补间。它在Unity中无处不在。掌握基本模式后,请进行实验。

    请注意,在我的示例中,代码使用 UnityEvent 来标记动画的开头和结尾。这非常普遍。通常情况下,一旦某些动作结束,你就必须继续做其他事情。另一个很好的例子是,虽然某些东西是动画,但是用户被阻止说转向或游戏中的任何情况。

    UnityEvent的优秀介绍https://stackoverflow.com/a/36249404/294884请将其投票:)

    记录。

    Unity中的Tweeng。

    Unity中补间的真正高级方法是tweeng:

    Basic Tweeng code base appears in this question.

    需要一段时间来掌握它,但它非常强大。令人难以置信的是,tweeng扩展只有几行代码。

答案 1 :(得分:0)

使用类似的东西,假设在1秒内旋转90度:

int rotatedDegrees; 
int desiredRotation = 90;
float startTime = null;
float rotationDuration = 1f;

public void rotate()
{    
  if(startTime == null)
    startTime = time.Now;

  while((time.Now - starttime) / rotationDuration > (((float) rotatedDegrees) / desiredRotation))
  {
    transform.RotateAround (isolatedAxisPoint, Vector3.up, 1);
    rotatedDegrees++;
  }
}

在startTime + 0时,它旋转了0度。

现在假设time.Now就像startTime + 0.1(+ 100ms)。然后是time.Now - startTime是0.1,旋转直到(rotateDegrees / desiredRotation)为0.1,即9,即总旋转的1/10。