1

我正在尝试在 Unity3D 中模拟一艘船。我需要它能够做的就是像一艘真正的船在水中碰到什么东西时会摇晃。我的船已经相撞了,它的所有轴都解锁了。然而,这意味着船会旋转,然后继续以奇怪的角度行驶(比如面向天空)。

有没有办法让船尝试返回其原始旋转,而不是捕捉到确切的值,而只是简单地来回“摇摆”,然后减速以最终再次停在正确的旋转处?


这是我尝试使用的代码:

void FixedUpdate ()
{
    wobble();
}

void wobble()
{
    if (this.transform.eulerAngles.x < 270)
    {
        this.rigidbody.AddTorque((float)19, (float)0, (float)0, ForceMode.Force);
    }
    else if (this.transform.eulerAngles.x > 270)
    {
        this.rigidbody.AddTorque((float)-19, (float)0, (float)0, ForceMode.Force);
    }
    else{}

    if (this.transform.eulerAngles.z < 0)
    {
        this.rigidbody.AddTorque((float)19, (float)0, (float)0, ForceMode.Force);
    }
    else if (this.transform.eulerAngles.z > 0)
    {
        this.rigidbody.AddTorque((float)-19, (float)0, (float)0, ForceMode.Force);
    }
    else{}
}

然而,现在当我的物体撞到什么东西时,它就开始失控了。有任何想法吗?

4

1 回答 1

5

您可以使用补间。一种在两个值之间平滑更改值的绝妙技术。在这种情况下,您可以通过在两者之间进行补间,从尴尬的弹跳角度到坐姿旋转的船进行补间。有很好的插件可以使用,比如iTween,这很棒,但我会向你展示一些半伪 - 半超级谷物代码,让你开始了解“旋转校正”的概念

可以说我的船遇到了一个很好的大浪,它把我的船向上指向了 20 度角。

我在 X 上的欧拉角是 20,我可以通过以恒定速率增加减小值来将其返回到 0。我只是在这里显示 X,但您可以对 Z 轴重复该过程。我会排除 Y,因为您将在 Y 上使用您的船方向,并且您不想搞砸您的船导航。

Update()

    float angleDelta;

    // check if value not 0 and tease the rotation towards it using angleDelta
    if(transform.rotation.X > 0 ){
        angleDelta = -0.2f;
    } elseif (transform.rotation.X < 0){
        angleDelta = 0.2f;
    }

    transform.rotation.X += angleDelta;
}

这个非常简单的实现可以完成这项工作,但具有令人难以置信的“活泼”和“紧张”的美妙优势。所以我们想添加一些平滑,使它成为一艘更栩栩如生的船。

我们通过向angleDelta添加一个变量来做到这一点:

Vector3 previousAngle;
float accelerationBuffer = 0.3f;
float decelerationBuffer = 0.1f;

Update()

    Vector3 angleDelta;

    //assuming that x=0 is our resting rotation
    if(previousAngle.X > transform.rotation.X && transform.rotation.X > 0){
        //speed up rotation correction - like gravity acting on boat
        angleDelta.X += (previousAngle.X - transform.rotation.X) * accelerationBuffer;

    } elseif(previousAngle.X < transform.rotation.X && transform.rotation.X > 0
        //angle returning to resting place: slow down the rotation due to water resistatnce
        angleDelta.X -= (previousAngle.X - transform.rotation.X) * deccelerationBuffer;
    }


    //If boat pointing to sky - reduce X
    if(transform.rotation.X > 0 ){
        transform.rotation.X -= angleDelta.X * Time.deltaTime;

    //If boat diving into ocean - increase X
    } elseif (transform.rotation.X < 0){
        transform.rotation.X += angleDelta.X * Time.deltaTime; //Must not forget to use deltaTime!
    }

    //record rotation for next update
    previousAngle = transform.rotation;
}

这是一个非常粗略的草稿,但它涵盖了我试图解释的理论——你需要相应地调整你自己的代码,因为你没有包含任何你自己的代码(粘贴一个片段给我们,也许我们可以详细说明更多的!)

于 2013-08-12T14:11:47.137 回答