Unity3D, “knocked away” type light object?

自古美人都是妖i 提交于 2019-12-07 22:19:30

问题


In a Unity scene, imagine

  • a large sliding object (perhaps a "shipping container" or a "sofa" sliding along for some reason)

  • in the way there are a number of 2m tall light wooden sticks lightly stuck in the ground.

in real life, the sticks would stand there (to begin with, this is annoyingly hard to achieve in PhysX actually), and when the large object hit them,

  • the large object would be totally unaffected

  • the sticks would be knocked away briskly, probably bounce off the ground once or twice and then land somewhere

I have found this quite hard to do in Unity.

Normally you'd say: "give the large object a mass of a few thousand, and the sticks a mass of only 1 or 2 kg".

However I found that really doesn't work - the sticks DO tend to swirl the large sliding object around.

And if you set the angular drag of the large object high, that's not then what you want for it's other behaviors.

In the first instance I made the sticks kinematic (so they would stand up without falling over) and then when the large object whacks it ..

protected void OnCollisionEnter(Collision collisionInfo) {

    rb.isKinematic = false;
}

Perhaps the only way to do this is

  • in fact, have the sticks totally unaffected in physics by the large object

  • when they touch (trigger), in fact just independently have the stick randomly "fly off". (Have the sticks only collide with the ground, scenery.)

How to do this in the Unity/PhysX milieu?


回答1:


(Converting my comment to an answer)

Small objects will affect large object in real life, but just slightly (so maybe there are too many sticks?). Or maybe the problem is in the way sticks are stuck into the ground? I've created test scene with cube (1000 kg) and some cylinders (1 kg). All objects are just standing freely on the ground. Here what it looks like when the cube hits cylinders:




回答2:


I did have great success "Booming" the pencil objects manually. As it may help someone, here's how.

As usually you'd have a separate trigger underneath the object on the appropriate layer:

public class BoomableTrigger : MonoBehaviour {

    public Boomable tell;

    protected void OnTriggerEnter(Collider other) {

        tell.Triggered(other.GetComponent<Rigidbody>().velocity);
    }
}

Then, to really "throw" it the hell forwards in a humorous way when your vehicle hits it ..

public class Boomable : MonoBehaviour {

    Rigidbody rb;
    // obvious setup not shown ..

    public void Triggered(Vector3 vehicleVelocity) {

        // (very likely tell your networking this happened ...)
        DoBoom(vehicleVelocity);
    }

    public void DoBoom(Vector3 vehicleVelocity) {

        // assume we are being hit by a large vehicle

        rb.isKinematic = false;

        // make it spring forwards humorously

        rb.velocity = vehicleVelocity * Random.Range(1f,3f);

        // and make it "snap-fall, forwards" ...

        Vector3 worldLeftwards =
           Vector3.Cross(vehicleVelocity, Vector3.up).normalized;
        rb.angularVelocity =
           worldLeftwards * -1f * Random.Range(5f,50f);
    }

That gives it a real Buster Keaton snap-fall, it "flies away" off the vehicle once the vehicle smacks it.

Experimentation showed for a nice comic effect, as well as throwing it forwards (the first clause), you really need to make it "fall forward" which takes a bit of vectoring.

It's not totally clear why it wouldn't just work naturally in PhysX as in @obywan's answer, possibly the kinematic flip. But if you have to do it that way this will work nicely.



来源:https://stackoverflow.com/questions/51960693/unity3d-knocked-away-type-light-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!