Search Unity

Is there a way to modify the effect of a collision?

Discussion in 'Physics' started by kritoa, Jun 15, 2019.

  1. kritoa

    kritoa

    Joined:
    Apr 21, 2017
    Posts:
    60
    Is there a way to (precisely) modify the effect of a collision on a rigidbody?

    I have a wall that I want to make essentially like a very strong glass window as part of a building, so I want it unmoving (no rigidbody at all, just a collider), so that when things hit it even with medium impact, the glass doesn't react or give way at all and the objects just bounce off. However, in a very strong contact (a bullet), I'd like to capture the collision (OnCollisionEnter), destroy the glass wall completely, and let the bullet pass through either with no slowdown or a slight slowdown.

    I've having a hard time making the object (bullet) pass through this glass without being slowed down that much.

    1) The collision and its effects have already happened by the time OnCollisionEnter is called, so Destroying the window doesn't let the bullet pass through unaffected.

    2) I see 'collision.impulse' is supposed to contain the total impulse applied to the objects by the collision, but applying the inverse of that impulse doesn't seem to undo it (i.e. this doesn't seem to work: collision.collider.GetComponent<RigidBody>().AddForceAtPosition(-collision.impulse, contactPoint, ForceMode.Impulse); )

    3) I can't make the window a trigger because I want most things (debris, pebbles, whatever) to bounce off of it).

    What's the right way for me to handle this? I'm in Unity 2017 (4.27f1)

    Thanks.
     
  2. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    I'm afraid there's no effective way to do this in Unity 2017. I'd try the trigger approach like this:
    • If the contacted object is a bullet just do nothing to it, mark the glass as "broken" and play the glass breaking effect.
    • Otherwise, compute a bouncing velocity for the incoming object and apply it as rigidbody.AddForce(bouncingVelocity - rigidbody.velocity, ForceMode.VelocityChange). This would make the object bounce against the glass. Also, ensure not to apply this consecutively to the same object (i.e. leave a couple of physics frames) to prevent them to get stuck in the middle of the trigger. Continuous Collision Detection would also be recommended.
    The upcoming ECS-based Unity Physics package (Unity 2019.1+) do allow this kind of advanced contact modification:

    https://github.com/Unity-Technologi...UnityPhysicsExamples/Documentation/samples.md

    These example scenes are about contact modification:
    • AddNarrowphaseContacts
    • ModifyContactJacobians
    • ModifyNarrowphaseContacts
     
    kritoa likes this.
  3. kritoa

    kritoa

    Joined:
    Apr 21, 2017
    Posts:
    60
    Ah, too bad; thanks for the reply.

    I don’t really want to go the trigger route, as some of these glass bits will be horizontal surfaces and I’m going to guess trying to make that method “use trigger and calculate bounce force myself” work with things resting on the glass surface will be basically impossible (and much more expensive since none of the resting objects can fall asleep).

    I think I will try putting a script on my bullets keeping track of position and velocity and after a collision, on the next fixed update after the glass has been destroyed, snapping it back to where it should have been with the velocity it should have had... that seems like it has a decent chance of working.
     
    Edy likes this.
  4. KouroshX98

    KouroshX98

    Joined:
    Feb 8, 2018
    Posts:
    24
    You can modify the collision matrix in setting.mark the bullet and glass as different layers and uncheck the collision between those two layers in setting -> Physics.now if you shoot the bullet it passes through the glass.but everything else collides with the glass.now place a trigger exactly where the glass is and as soon as the bullet enters that trigger,destroy the glass.
    Good Luck!
     
    kritoa and Edy like this.
  5. kritoa

    kritoa

    Joined:
    Apr 21, 2017
    Posts:
    60
    Thanks! That option would definitely work except for the cases where some fast moving objects that aren’t bullets should break the glass - that is, bullets aren’t the only thing that should be able to break it - other heavy/fast things should as well, like other bits of debris from nearby explosions.

    But in the case where only bullets can break it, that is a nice elegant solution - thanks.

    FYI in case anybody finds this thread: my solution is a little grosser but it works: I have a script on my bullets which keeps track of the bullet’s rigibbody’s position, velocity, rotation, angular velocity. There’s a script on glass which has an OnCollisionEnter method which checks for a high force impact, and if it sufficiently powerful the glass shatters and if and the collider is a bullet, it will notify the bullet that it broke something

    If the bullet gets the notification, in FixedUpdate it will set its position to the last position plus the last velocity * fixedupdatedeltatime, the velocity to velocity + gravity * fixedupdatedeltatime, and the equivalent for rotation.

    This seems to work just fine. I haven’t tested it yet with continuous collision detection yet as it hasn’t been necessary yet.

    The only “issue” is that either I also need to add this “restore bullet to old velocity” script on all pieces of debris, rubble as well, or I just have to be ok with debris/rubble bouncing off the glass even if it shatters it (the latter option is good enough for my needs so I’m considering the problem solved).
     
  6. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    What I tend to do is raycast from the bullet to where he's gonna be next update and see if he hits anything that needs to have some kind of reaction.

    in this case I'd let the bullet ignore the glass but let the raycast detect it one frame in advance, if the speed is great enough - break the glass in script, the bullet shouldn't be bothered, if it should bounce calculate the angle and move it.

    this also makes it so you don't need to worry about the collision detection mode and keep it at discreet, just gotta link the raycast to whatever it would have hit.
     
    kritoa likes this.