Prevent Rigidbodies from pushing each other

Nobody appear to have the answer to this one, but it’s quite important. In short, how to replicate Dark Souls or Bloodborne character collisions.

Let’s assume a system with an unknown number of rigidbody, each moving around at different unknown velocities driven by gravity, physic or by animation. Some rigidbody cannot push each other, while other can.

A character can NEVER push another character. A character never transfer energy/impulsion/velocity to another. However, they still collide with each other. A character can be pushed by other rigidbody like an explosion, a trap, attacks, etc. A character can push other rigidbody like debris or breakables.

How to do that?

If it’s not clear what we want, I’ll go record a video in Dark Souls.

It’s just Kinematic motion: [2d] [Isometric] - How to disable pushing between two characters - Unity Engine - Unity Discussions

No, it’s not, because we still need to collide with everything else like a normal none-kinematic rigidbody. And our motion is animation-driven, not code-driven.

It’s simple Physic Layer A and Layer B does not share energy/impulsion on collision.

Here’s an example of Dark Souls inter-character collisions;

The player(s) is moving forward, but it never push another character. Works no matter the number of character around. Two character can run towards each other, and they still cannot push each other.

Found out that PhysX does offer a way to do this using Contact Modification: Advanced Collision Detection — NVIDIA PhysX SDK 3.4.0 Documentation

However, Unity never exposed it. You can vote on this feature here; https://feedback.unity3d.com/suggestions/physics-contact-modification

Contact modification can offer a lot more behaviours.

BUMP

how is this not a thing yet? this post is almost two years old.

1 Like

Agreed…

I ended up checking which character has lower speed on collision and increase the weight 100 fold for it.

However it doesn’t work properly and would like to have a more robust solution.

Is this still not a thing?

We just got copy-paste on the inspector. Give Unity 5-10 more years.

I don’t see how what’s in the video would be difficult to implement. That just looks like keeping a minimum distance to me - for example watch the shields, nothing moves, there’s no interaction or animation of any contact whatsoever. I can’t even be sure from that if physics is being used at all for movement.

There are a couple of reasonably quick ways I can think of to make things work like the video - maybe someone finds this useful. In all of them, you’d start by making the layers not collide with each other (in Project Settings). Then you could either 1) define a radius and use Vector3.Distance with any current candidates for collision to keep a Rigidbody a given minimum distance away from whichever others, which would be a lightweight approach for radial avoidance. 2) create a ghost object and have the collider set to Trigger, then use OnTriggerEnter to move a belligerent back to the nearest point at the minimum distance (which would be at/just outside the collider).

For a sphere you can just set to direction normalized times the radius you want, keeping in mind floor contact (maybe replace Y component of result with what it was at time of contact, or raycast for new Y offset from ground if that’s not enough for more complex surfaces), for lightweight capsule-ish handler you could do the same but multiply the Y component before comparing distance to “stretch the sphere vertically” where the math is concerned. Anyway, this is just to demonstrate there are ways to achieve it - the exact approach would vary and be more or less complicated based on the precision of the handling needed.

Video solution

2 Likes

I prevent Character A from pushing Character B just by sweeping the body towards the movement direction (just like kinematic character controllers do). If a rigidbody is found, then i ask: "Should the character push this object?"If so, then let the physics do the job. if not, then modify the velocity using the collide and slide algorithm (the character in video is sliding at 0:06-0:07).

See 1:56

(C’mon Unity forum! Timestamps do not work at all… it is almost 2021)

BTW “Contact modification” is being developed:

1 Like

How in the hell isn’t this a basic functionality of a game engine? 2 sprites prevent “collision” without additional physics on top of that. Is it really that difficult? Elementary free javascript engines like phaser have this functionality, and I’m expected to write my own scripts to do the most basic of things in a paid engine in 2021?

3 Likes