Walls Mysteriously Repelling Rigid Body Player Character

I’m running into a really strange scenario where having the player character jump while standing next to a wall exerts a strange repelling force away from the wall.

The behaviour is somewhat inconsistent, but seems to be influenced by:

  • how close the player is to the wall, it only really seems to happen when the colliders are directly touching.

  • (This seems the biggest factor) if the top of the wall is a different mesh than the bottom of the wall. This seems to “hiccup” something in the collider when it’s transitioning between the two meshes. and pushes it away

The below screenshots demonstrate before starting the jump action, and the result after jumping. The character controller is based around a rigid body.

This is really confusing, as the material settings for the player character (while jumping) are set to:

  • 0 friction
  • 0 bounciness
  • minimal drag
  • friction combine set to minimum
  • bounce combine set to minimum
  • rigid body continuous, and interpolating

The speeds involved are also really low (velocities magnitude < 4)

The only applied force is directly upwards, and there shoudln’t be any direct forces being applied towards or away from the wall (code snippet below).

Any ideas what may be causing this?

Video of interaction

The top half of the cliff here is a separate mesh than the bottom half (this instance could probably be fixed, but there will be other instances where this would be unavoidable).


The code to enter the jump state is as follows:

 // enter jump state.
// reset jump power.
mc.jump_persist_energy = PlayerConstants.JUMP_PERSIST_ENERGY_MAX;
// add jumping force.
mc.rigid_body.velocity = new Vector3
     (mc.rigid_body.velocity.x, 0, mc.rigid_body.velocity.z);
mc.rigid_body.AddForce(Vector3.up * PlayerConstants.FORCE_MULTIPLIER_CROUCH_JUMP, ForceMode.VelocityChange);
// player sound.
mc.audio_source.clip = mc.sfx_player_crouch_jump;
mc.audio_source.Play();

This seems to be an issue of discontinuity between any surface where two mesh colliders meet.
Both horizontal and vertical seem to follow the same pattern.


Here the circle represents the character and the squares represent the world geo / mesh colliders.

It’s less obviously horizontally because gravity is always working to push the character downwards. But vertically you get the behaviour above. This only seems to happen when the colliders are touching.

Not sure what to do, I’ve tried various modes on the rigid body, discrete continuous, speculative, interpolative, etc.

Whilst you’re talking about 3D here, it’s the same in 2D. Here’s a post that explains it pretty well albeit for 2D.

I am not a 3D physics dev but I believe you can use the new 3D physics contact modification to help work around this issue which is inherent to most physics engines.

Thanks for the link! Very informative. I might not have the right terminology, but it doesn’t seem there is any 3D analogue to the ghost vertices solution.

Do you have a good jumping off point regarding the “new 3D physics contact modification” ?

This might be the best to start with: Experimental contacts modification API

That’s awesome, thanks for your help.

For anyone else finding this thread, I may also add that reducing the “Default Contact Offset” in the physics settings from 0.01 to 0.001 practically eliminated this issue for me!

But, I’m sure this has some performance impact.

This stuff might affect it but nothing will eliminate it like that and you’re likely to cause other collision detection issues because you just reduced the contact offset margin by an order of magnitude. That value isn’t like that because it’s random, it’s a finely tuned parameter.

Ah I see, no disrespect intended by the above post - it’s just a very promising thing to find. An initial testing all aspects seem the same, while the behaviour above is eliminated.

Do you have any suspicions on what problems reducing this might cause?

No disrespect seen, I was just cautioning you. :slight_smile:

As I said, I’m not a 3D physics dev (I’m a 2D physics dev) but the results are likely to be similar.

Some info here and there’s likely more. You’re essentially searching for “physx contact offset”.
https://docs.unity3d.com/Manual/class-PhysicsManager.html
https://docs.nvidia.com/gameworks/content/gameworkslibrary/physx/guide/Manual/AdvancedCollisionDetection.html

Greatly appreciated, many thanks.