Prevent rigidbodies from pushing each other?

I have a player and an enemy, and they both have rigidbodies on them. When they touch it’s possible for them to push each other, which I don’t want. Is there an elegant way at preventing them from pushing each other while still being able to collide with each other? Something like, ignoreCollisionForce() or something.

Thanks.

Maybe Unity - Scripting API: Physics2D.OverlapArea
check for overlap and set to trigger… so they will not push each other…

But what exactly do you want to make it happen when they meet? If there were no forces they would pass right through each other. Maybe you want them to stick together?

For one thing I wouldn’t want them to overlap each other at all either, and they are going to be colliding with other things so I’m not sure if triggers are the best solution.

Basically I want them to act like walls to each other. I currently set the player’s X velocity to 0 when it comes within a short raycast of the enemy, but the raycast isn’t always reliable (for example, my raycast is .2f long to stop the player, but sometimes the player can still get closer than that). Triggers also aren’t reliable to keep the player from getting closer than it should.

You could add a parameter to your raycast length that increases it based on a fraction of your rigidbody.velocity.x. This way it will take into account the margin for error in physics steps from speed increases.

Basically you want them to have inelastic collisions. How about altering the physics material, set the bounciness to zero whenever they touch each other.

How do people have floating panels that you can walk on without pushing them down, or wall jump off of falling rocks without pushing the rocks to the side? It’s the same problem, so if someone knows how to have that done then it’ll solve mine.

This didn’t work for me; they can still push each other around sadly.

This could be a possibility… but getting it to work perfectly might end up being more effort than it’s worth. I might end up needing to do this though, or perhaps just scrap my controller and do this without Unity’s physics engine :frowning:

In these examples the player (dynamic body) is interacting with other objects (kinematic body).
In your case you actually have a dynamic body interacting with another dynamic body.

What if you make your player a dynamic body, and make your enemy a kinematic body?

In box2d physics…

  • Dynamic body colliding with Dynamic body results in both bodies pushing each other
  • Dynamic body colliding with Kinematic body results in Kinematic body acting like a wall (a wall that can move if it chooses to, but will not move if the dynamic body collides into it)
  • Dynamic body colliding with Static body results in Static body acting like a wall (a wall that can not move if it chooses to, and will not move if the dynamic body collides into it)
  • Kinematic body colliding with Kinematic body results in them actually passing right through each other
  • Kinematic body colliding with Static body results in them actually passing right through each other
4 Likes

This sounds promising, but how can I move a Kinematic body while still getting collisions? Setting the velocity/adding forces doesn’t move it, and transform translate goes right through colliders. I noticed there’s a MovePosition for 3D, but there is no MovePosition function for 2D rigidbodies.

That is very odd. That SHOULD move it.

1 Like

Oh shoot, you’re right it does move. I forgot to enable my script :P. Thanks Kurius and company, I’ll see where I can go from here.

EDIT: It moves, but now it doesn’t collide my walls/floor :confused: any suggestions?

Yup as I mentioned earlier a kinematic body will travel through a static body. So unfortunately you’re once again left with trying to detect proximity to a wall etc then negating the force or velocity manually so that the enemy doesn’t travel through the wall.

I see. I was able to reuse my player’s wall/groundcheck raycasts for the enemy collisions, and now the enemies won’t be pushed around by the player. It also seems that Kinematic rigidbodies don’t respond to triggers, so I’m going to implement something similar to what AlenBrk suggested with OverlapArea (which on it’s own doesn’t work all of the time since it only gives back one collider, wheras I’d need to check hits on multiple enemies in one spot).

It looks like my game isn’t on ice yet thankfully; if it was multiplayer I might have been stuck haha. Thanks all, I hope this is the last of my worries with Unity’s collision engine.

I think the issue of kinematic bodies not responding to triggers is a bug. You can search this forum about it.

I looked at the bug report, and apparently it’s supposed to be like that by design and the docs are just wrong. Strange, but here’s the report if anyone’s interested. It sounded like one of the Unity guys might be implementing the feature though, but I have no time to wait on that :).

Bug Report listed as “By Design”

Edit: It looks like using OverlapAreaNonAlloc() will snatch a list of colliders over a rectangle! So if anyone is in the same place as me you could use that or OverlapAreaAll (this one returns a list while allocating memory, the former takes a reference to an array and edits it).

New to Unity, but just to give another way to solve this issue…

  1. is to set the gravity scale on the rigidbody to a high level so that player interaction does not move it
  2. is to add an empty child with a collider and set the parent as a trigger.

I know this is an old question, but still very relevant.

1 Like

This is definitely still relevant. I’d like to try your ideas, but they don’t make sense to me. I don’t see any such property as gravity scale for a rigidbody so I can’t try that option. For the second option could you explain in more detail? I’m not quite sure what you’re suggesting here.

@night5415
@magique

I am sorry that I can not give you a working solution to your problem.
However, Physx actually has a function to handle these cases, but unfortunately it is not currently exposed in unity yet, as you can see:
https://feedback.unity3d.com/suggestions/physics-contact-modification

I encourage you to vote for that feature, if you also thing that adding that feature to the Unity API would be a great addition!

Since Unity doesn’t plan on exposing those features for the devs any time soon, I managed to create that behaviour almost perfectly:

  1. You’ll need 2 colliders, both attached to identical rigidbodies, and one being the other’s child. Let’s call the parent “World Collider” and the child “Player Collider”.

  2. World Collider is a regular collider and its rigidbody is dynamic. The gameObject should be in a layer Player, that will be used by every collider that wants to collide with the player, except for other players.

  3. Player Collider is a trigger collider and its rigidbody is kinematic. The gameObject should be in a layer Player Collider, that will serve one purpose only: to collide with other players’ World Colliders.

  4. Adjust the Layer Collision Matrix to the following image: Layer Collision Matrix to prevent players from pushing each other in Unity3D - Album on Imgur

The players still push each other a little, but I’m sure you could adjust some mass settings and be able to achieve the wanted result. I’m not worried about it being perfect yet, but let me know if it works.

1 Like

set the rigidbody.drag to about 20, that will probably solve the problem

1 Like