Colliders passing through each other, even with Continuous Collision Detection

Hi there!

I’ve been investigating this for the better part of a week, and I could really use some help here :frowning:

Context:
I have a character that performs a quick dash using RigidBody.MovePosition(). This character object has a rigidbody that is NOT kinematic, it is set to Continous Collision Detection, and has a cubic collider of roughly 1.3 units.

The dash moves non-linearly, traveling 18 world units in ~0.5 seconds

I have GameObjects in the scene that have nothing but a colliders on them, acting as barriers in the map.

Issue:
From what I can tell, unless my colliders have a thickness of 3 units or more, I can still manage to pass through the barrier colliders, even if my character has a Continous Collision Detection set.

Secondly, I also seem to be running into issues where the character can especially pass through easily by dashing towards the intersection of two colliders that are perpendicular to each other. It’s like the motion sticks to the intersction between the colliders and passes the character all the way through.

Attempts to resolve:
I’ve also tried giving the barrier colliders a rigidbody and setting their collision detection to continuous, and then changing my characters detection to Continous Dynamic. But this still has no effect.

I’ve also lowered the fixed time step in the project settings from 0.02 → 0.01. This seems to be better, but i still run into issues. I can mostly get it fixed if I set it to 0.005 however.

Questions:

  • has anyone else run into issues like this?
  • What might be going wrong? Is it that my game is just scaled way too high up? i.e 18 world units is too much to travel in that short amount of time?
  • Also, has anyone lowered their fixed time step that much? Is 0.005 too ridiculous of a low number?

Thank you so much in advance for any help you can offer :slight_smile:

1 Like

Hi ShervinM!

What you have to consider here is that, from a physics standpoint, transform.Translate and rigidbody.MovePosition are pretty much identical.
In both cases, you’re changing the position of a rigidbody instantly and then have to pray that the physics engine somehow resolves the mess without putting your character on the wrong side of a wall.

Generally speaking, I’d not recommend moving characters with rigidbody.MovePosition at all. Try to modify the rigidbodies’ velocity instead if you need instant movement like that.

Well, that value means that your computer now has to calculate 200 physics frames per second (1 / 0.005 = 200). Not really practical, unfortunately.

In my experience, there’s little to no reason to go beyond a fixed timestep of 0.016 ( = 60 frames/second) for most games.

4 Likes

Hi JanOtt!!

First and foremost, thanks so much for taking the time to respond to my post! I really appreciate your help!

I’ve already started to use AddForce as well as setting Rb.velocity directly and I’m starting to see improvements with collision detection! I had completely misunderstood how rb.moveposition worked. Thank you so much for this tip!

Doing some experiments, I do still wonder how I can amend my code to set the rigidbody velocity directly. I’m setting the velocity directly in fixed update, but it seems like my movement stutters much more than before. Have you run into this? Is this a side effect of manipulating the velocity directly? Is there any way to set higher velocities while still maintaining smooth motion in between?

Generally speaking, you should be able to get smooth movement by setting the rigidbody velocity directly, even at higher speeds. There’s a few things that could be causing the stuttering you’re experiencing. Here’s a checklist you can try to figure out the problem:

  • Set ‘fixed time step’ back to something reasonable (0.02), if you haven’t already.
  • Make sure to activate interpolation on your rigidbody in the inspector.
  • Make sure that your code doesn’t include any transform.Translate() or rigidbody.MovePosition() calls - this can break rigidbody interpolation or cause stuttering.
  • Use a reasonable scale when building your level → 1 Unity unit = 1 meter is generally recommended.

If none of the above fixes your problem/stuttering, then the next thing to check would be how you calculate the velocity in your code.

2 Likes

Hey @JanOtt or even @ShervinM .
A lot of years passed by since you both talked in this post, but I started working on Unity for 5 months now so I’m trying to get the best practices. I was having the same issue that @ShervinM had and came across this post and I wanted to ask what is the most suitable way to move rigidbodies.
I’m working on a 2D top-down and I was using the rigidbody.MovePosition() to move the player, but I’ll update it, I just don’t know what should be the best approach to change it, to use velocity or forces.

I would be grateful if some of you could help me a bit

What is the most appropriate way to eat? The reason I ask this is because it’s a vague question and requires some context or extra information. There isn’t a “most suitable” way! :slight_smile:

There is only a description of what MovePosition (and MoveRotation) does and whether this is what you want. MovePosition moves to the position during the next simulation step by temporarily overriding the Rigidbody velocity (the actual velocity is restored after) to cause it to move so it is using velocity to do so. It doesn’t change how collision detection and response works, that is controlled by other aspects i.e. what body-type the Rigidbody is (dynamic/kinematic) and whether the Collision Layer Matrix allows contacts on specific layers.

2D top-down doesn’t change anything. The physics system doesn’t know this, it’s just a visual thing.

So in short, MovePosition just uses velocity to move to the position in the next simulation step. It’s essentially nothing more than a helper and you could do the same yourself.

Im also having problems with this

Do you have to have rigidbodys on them to collide

I had a similar Problem, When I went into Layer Overrides and set Include Layers to Everything It just started to work.

Which means that you’re overriding the layer collision matrix which itself means that you’ve not set that up correctly. Overriding is meant for specific scenarios, not the basis for controlling what can contact what.

I reply to this so that others reading it don’t get that impressions.

What can contact what is a basic thing that 100% works otherwise there’d be pitchforks and fire on the forums. :wink: