简体   繁体   中英

Get an object to wobble in Unity3D with C#

I am trying to simulate a boat in Unity3D. What I need it to be able to do is wobble like a real boat would while in water whenever it hits something. I have the boat colliding already, and all of its axes are unlocked. However, this means the boat will rotate, and then keep driving at an odd angle (like facing to the sky).

Is there a way to make the boat try to return to its original rotaions, without snapping to the exact values, but simply "rocking" back and forth, and then slowing down to eventually stop at the correct rotations again?


Here is the code am attempting to use:

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{}
}

However, now when my object hits something, it just starts spinning out of control. Any ideas?

You can use tweening. A wonderful technique to change values smoothly be- tween two values. In this case you can tween from your awkward bouncing angles to your boats sitting rotation by tweening between the two. There are good plugins to use like iTween which is fantastic but I will show you some half pseudo - half super-cereal code to get you started on the concept for "rotation correction"

Lets say I have my boat hit a nice big wave and its pointing my boat upwards to a 20deg angle.

My euler angle on X is 20 and I can return this to 0 by increasing the decreasing the value at a constant rate. I'm just showing X here but you can repeat the process for Z-axis. I would exclude Y as you will use your direction of your boat on Y and you don't want to screw up your boats navigation.

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

This incredibly simple implementation does the job but has the wonderful perk of being incredibly "snappy" and "jittery". So we want to add some smoothing to make it a more lifelike boat.

We do this by adding in a variable to the 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;
}

This is an incredibly rough draft but it gets across the theory that I'm trying to explain - you will need to adjust your own code accordingly as you haven't included any of your own (pastebin a snippet to us and maybe we can elaborate more!)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM