2016-05-13 135 views
1

我正在写一个函数,在一段时间内缓慢转动90度。到目前为止,一切工作正常,我只需要弄清楚如何使它围绕转换中心旋转一点而不是旋转。Unity3d随着时间的推移围绕一个特定的点旋转

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旋转?

+0

在该点周围绘制一个圆并沿着该圆移动它? – Master117

+0

这听起来像是会起作用,我对统一很陌生我使用'Quaternion.Lerp'或'Quaternion.Slerp'作为那个 –

+1

,你可能会很好地研究[旋转](http:// docs。 unity3d.com/ScriptReference/Transform.RotateAround.html),结合'速度* deltatime',您可以添加缓解,甚至时间 –

回答

5

下面是一个实际的示例Unity Tween碰巧在文本编辑器中显示的另一个窗口!

如果要旋转的东西,实在是小巫见大巫只是使用的DeltaTime在一个IEnumerator一个循环,并调整为:eulerAngles或只是调用旋转。 (在Unity中从不使用四元数。)在这个例子中,我只是调用Rotate。

这是一个Unity的基本模式

以下是Unity中补间的基本图案。你会在Unity中做这1000次!

  1. 计算结束时间
  2. 做一个while循环,直到达到该时间
  3. 每个帧,滑动(或其他)由适当的级分。

注意,当然,你

yield return null; 

内循环的,它的意思是“等到下一帧”。

(请注意,与任何吐温,这是很好的做法,强制设定的最终值在年底,所以你知道它是完美的。在这个例子中,我简单地设置为: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(); 
    } 

{注意,在实际的代码示例中,“增量”理解为仅在一个轴上;不用担心,这只是一个使用协程的补间的例子。}

注 - 当然有“两种方式”去循环内。你可以计算小数目你应该把它移动到那个框架。或者,您可以计算当时应该在的新位置。随你便。许多程序员认为后者更合乎逻辑,如果是这样的话。还要注意的是,你可以在while循环中执行while循环,直到你到达目的地为止! (非常小心浮动平等。)选择是你的。非常非常经常使用线性插值甚至更​​好SmoothStep与这些充斥着的是

注意。它在Unity中无处不在。一旦你掌握了基本模式,就尝试一下。

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

优秀的介绍到UnityEvent https://stackoverflow.com/a/36249404/294884请投上一票:)


为了记录在案。

Tweeng in Unity。

的是先进的方式统一补间是tweeng:

Basic Tweeng code base appears in this question.

这需要一段时间才能得到的,该悬挂却是令人难以置信的强大。令人惊讶的是,tweeng扩展只有几行代码。

+0

谢谢,这就是我正在寻找的东西,当我回家时我会测试这个,只是想知道是rollComplete一个内置的代表?还是某种类型的事件系统,可以防止它被称为多重时间直到它完成? –

+0

谢谢,关于设置我在角度之前注意到的末端欧拉角度的提示,我们稍微介绍一下,可能是因为四舍五入的浮点十进制错误 –

+0

嗨,约翰尼,这是Unity中正确的模式。它就像是最基本的东西,有时候感觉就像你在Unity中编程一样,嘿! “rollComplete”是一个“unityEvent”,我已经包含了一个完整的解释。这样的协同补间就是使用UnityEvent的一个很好的例子。 – Fattie

0

使用类似,假设由90度在1秒旋转:

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

在开始时间+ 0它已经旋转0度。

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

+0

hm有趣,但time.Now如何与rotateDegrees/desiredRotation相关,不是时间,现在总是增加,或者不应该在协程中使变量不修改? –

+0

@ johnny5编辑,time.Now - startTime =自旋转开始以来的时间。 – Master117

+0

谢谢,当我回家时,这看起来很稳定。如果它的工作,我会把它标记为完整 –