Unity 3D在时间

时间:2015-11-28 18:53:35

标签: c# unity3d rotation

我正在编写一个游戏,其中每当节拍器敲打时立方体必须绕其自身旋转90度。

每次节拍器跳动时,我的方法都会调用一个协程:

IEnumerator moveCoroutine()
{
    if (!isCollided && canRotate) {
        for (float i = 0; i < 10; i++) {
            transform.RotateAround(pivot, direction, 90 / 10);
            yield return null;
        }
    }
}

并且立方体旋转相当平滑,但旋转在节拍器的下一个节拍之前很长时间完成,并且我希望它从开始到结束旋转,顺利移动。

我想我可以使用两个节拍器刻度之间的时间(这是var&#39; Metronome.manager.delay&#39;)但是我找不到如何。

感谢您的帮助

4 个答案:

答案 0 :(得分:0)

您可以在Mathf中使用SmoothStep函数:http://docs.unity3d.com/ScriptReference/Mathf.SmoothStep.html

最小值是立方体的当前角度,最大值是当前角度+ 90,t类似于(currentTime - previousTick) / (nextTick - previousTick)(根据您的数据结构进行修改)

答案 1 :(得分:0)

所以你的Unity c#脚本通常会在每个帧渲染时运行。为了使您的动画流畅,您需要根据文档将您的更改字段/变量乘以Time.DeltaTime

http://docs.unity3d.com/ScriptReference/Time-deltaTime.html

Time.DeltaTime由统一游戏引擎计算,是从上次渲染帧开始经过的时间。

文档中的示例:

public class ExampleClass : MonoBehaviour {
    void Update() {
        float translation = Time.deltaTime * 10;
        transform.Translate(0, 0, translation);
    }
}

在该示例中,变换在z轴上被翻译了10个单位,由于Time.deltaTime [校正因子]而正确地进行了动画处理。

  

如果你在每一帧中添加或减去一个值,你应该有机会   乘以Time.deltaTime。当你与Time.deltaTime相乘时   你基本上表达:我想把这个物体移动10米   而不是每帧10米。

使用协程的另一个例子:

using UnityEngine;
using System.Collections;

public class CoroutinesExample : MonoBehaviour
{
    public float smoothing = 1f;
    public Transform target;


    void Start ()
    {
        StartCoroutine(MyCoroutine(target));
    }


    IEnumerator MyCoroutine (Transform target)
    {
        while(Vector3.Distance(transform.position, target.position) > 0.05f)
        {
            transform.position = Vector3.Lerp(transform.position, target.position, smoothing * Time.deltaTime);

            yield return null;
        }

        print("Reached the target.");

        yield return new WaitForSeconds(3f);

        print("MyCoroutine is now finished.");
    }
}

你想要的可能是这样的:

IEnumerator moveCoroutine()
{
    if (!isCollided && canRotate) {
        for (float i = 0; i < 10; i++) {
            transform.RotateAround(pivot, direction, 9.0f * Time.deltaTime);
            yield return null;
        }
    }
}

这可以修复动画的平滑度,并使其独立于每台计算机渲染帧(FPS)的能力。 - &GT;问题只有当你在自己以外的其他设备上进行测试时才会注意到。

现在解决动画长度的问题:

IEnumerator moveCoroutine()
{
    int maxIterations = 10;
    if (!isCollided && canRotate) {
        for (float i = 0; i < maxIterations; i++) {
            transform.RotateAround(pivot, direction, 9.0f * Time.deltaTime);
            yield return new WaitForSeconds(Metronome.manager.delay / maxIterations);
        }
    }
}

WaitForSeconds(Metronome.manager.delay / maxIterations);将确保您的动画在您想要的时间播放。 (请注意,Metronome.manager.delay如果尚未转换为秒,则需要转换为秒。

答案 2 :(得分:0)

这是一个协程,你只需要为waitforseconds指定一个值。监控游戏并根据需要设置值。

IEnumerator moveCoroutine()
    {
         float time=0.5f;
        if (!isCollided && canRotate) {
            for (float i = 0; i < 10; i++) {
               transform.RotateAround(pivot, direction, 9);
                yield return new WaitForSeconds(time);
            }
        }
    }

答案 3 :(得分:0)

其他答案可能有用..但是我使用此设置来实现Unity中的平滑协同程序,而不是取决于帧速率而是实际时间 (运动的必要变化应该是微不足道的):

touch million-subfolders-folder/package.json

通过这种方式,您可以更自如地控制动画所需的时间,并为旋转设置精确值,确保旋转时不会出现任何奇怪现象。

你可以称之为Coroutine而不是例如。

public IEnumerator RotateCoroutine(Vector3 rotationEulerAngles, float rotationDuration)
{

    /* Set the current goal Rotation to animate between them */
    Quaternion currentRotation = transform.localRotation;
    Quaternion goalRotation = currentRotation * Quaternion.Euler(rotationEulerAngles);

    /* Set control variables */
    float timePassed = 0.0f;
    float fracTime = 0.0f;

    /* Begin the animation, end after rotationDuration seconds */
    while (fracTime < 1)
    {
        /* Set Rotation between current and goal depending on fracTime */
        transform.transform.localRotation = Quaternion.Lerp(currentRotation, goalRotation, fracTime);

        /* Update timePassed and fracTime */
        timePassed += Time.deltaTime;

        /* On this way fracTime will always be a value between
        * 0 - start of animation and
        * 1 - end of animation after rotationDuration seconds */
        fracTime = timePassed / rotationDuration;

        /* yield return so the actual state gets printed */
        yield return null;
    }

    /* Just to be sure after the animation set yourGameObject
     * to exactly the tranformation value(s) you want */
    transform.localRotation = goalRotation;
}

用于在当地的Y轴

中在2秒内旋转对象约90°