【问题标题】:Lerp vs tweeningLerp 与补间
【发布时间】:2016-08-17 07:21:40
【问题描述】:

我正在尝试根据用户输入(例如键盘左/右箭头)旋转对象(在一个轴上)。我正在使用 Rigidbody 和方法 MoveRotation

所以在FixedUpdate 中,我正在使用Mathf.Lerp 创建与帧无关的角运动。

rotation = Mathf.Lerp(rotation, rotation + input, Time.deltaTime * speed)

但这是线性的,我想平滑这个旋转(例如Sine.easeIn),所以它开始慢慢旋转,过了一会儿它就完全旋转了。

在 Unity 中,将补间与用户输入和帧独立性相结合的最佳方式是什么。 (我想我不能使用像 DOTweeniTween 这样的库,因为不知道补间的时间。

【问题讨论】:

  • 您想在某个点限制旋转还是继续加速?您还必须使用补间还是考虑物理引擎?
  • 假设我想在某个时候设置它的上限(也可以使用tweening),但是这个可调整的上限不是我主要关心的问题。我想使用纯数学(但知道两种解决方案都会很好)
  • 你检查我提供的答案了吗?

标签: c# unity3d tween


【解决方案1】:

您可以使用Physics 围绕其轴加速对象。

Rigidbody.AddTorque(torqueVector3, ForceMode.Accelerate);

您需要添加一个刚体才能使其工作,根据 Unity 文档将参数 ForceMode 设置为加速:

为刚体添加连续加速度,忽略其质量。

您可以添加一些代码来限制我认为的速度,例如:

if (Rigidbody.velocity.magnitude >= capAmount)
{
    Rigidbody.velocity.magnitude = capAmount;
}

另一种更通用的上限轮换方式是更改max angular velocity

【讨论】:

  • 那么使用自定义插值方法,而不是物理引擎呢?
【解决方案2】:

所以它开始慢慢旋转,过了一会儿它就完全旋转了 旋转。

这可以通过协程来完成。启动协程并在 while 循环中执行所有操作。当按下左/右箭头键时,有一个随时间递增的变量Time.deltaTime

public Rigidbody objectToRotate;
IEnumerator startRotating()
{
    float startingSpeed = 10f;
    const float maxSpeed = 400; //The max Speeed of startingSpeed

    while (true)
    {
        while (Input.GetKey(KeyCode.LeftArrow))
        {
            if (startingSpeed < maxSpeed)
            {
                startingSpeed += Time.deltaTime;
            }
            Quaternion rotDir = Quaternion.Euler(new Vector3(0, 1, 0) * -(Time.deltaTime * startingSpeed));
            objectToRotate.MoveRotation(objectToRotate.rotation * rotDir);
            Debug.Log("Moving Left");
            yield return null;
        }

        startingSpeed = 0;

        while (Input.GetKey(KeyCode.RightArrow))
        {
            if (startingSpeed < maxSpeed)
            {
                startingSpeed += Time.deltaTime;
            }
            Quaternion rotDir = Quaternion.Euler(new Vector3(0, 1, 0) * (Time.deltaTime * startingSpeed));
            objectToRotate.MoveRotation(objectToRotate.rotation * rotDir);
            Debug.Log("Moving Right");
            yield return null;
        }
        startingSpeed = 0;
        yield return null;
    }
}

只需从Start() 函数启动协程一次。它应该永远运行。它会慢慢地旋转到快,直到到达maxSpeed

void Start()
{
    StartCoroutine(startRotating());
}

您可以修改 startingSpeedmaxSpeed 变量以满足您的需要。如果您认为到达maxSpeed 需要很长时间,您可以随时将startingSpeed 与另一个数字相乘,然后再将Time.deltaTime; 加到它上面。比如把startingSpeed += Time.deltaTime;改成startingSpeed += Time.deltaTime * 5;

【讨论】:

    猜你喜欢
    • 2022-08-08
    • 2017-09-28
    • 1970-01-01
    • 2014-06-02
    • 2017-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多