How to prevent colliders from passing through each other?
Solution 1
Collision with fast-moving objects is always a problem. A good way to ensure that you detect all collision is to use Raycasting instead of relying on the physics simulation. This works well for bullets or small objects, but will not produce good results for large objects. http://unity3d.com/support/documentation/ScriptReference/Physics.Raycast.html
Pseudo-codeish (I don't have code-completion here and a poor memory):
void FixedUpdate()
{
Vector3 direction = new Vector3(transform.position - lastPosition);
Ray ray = new Ray(lastPosition, direction);
RaycastHit hit;
if (Physics.Raycast(ray, hit, direction.magnitude))
{
// Do something if hit
}
this.lastPosition = transform.position;
}
Solution 2
I have a pinball prototype that also gave me much trouble in the same areas. These are all the steps I've taken to almost (but not yet entirely) solve these problems:
For fast moving objects:
Set the rigidbody's Interpolate to 'Interpolate' (this does not affect the actual physics simulation, but updates the rendering of the object properly - use this only on important objects from a rendering point of view, like the player, or a pinball, but not for projectiles)
Set Collision Detection to Continuous Dynamic
Attach the script DontGoThroughThings (https://www.auto.tuwien.ac.at/wordpress/?p=260) to your object. This script cleverly uses the Raycasting solution I posted in my other answer to pull back offending objects to before the collision points.
In Edit -> Project Settings -> Physics:
Set Min Penetration for Penalty to a very low value. I've set mine to 0.001
Set Solver Iteration Count to a higher value. I've set mine to 50, but you can probably do ok with much less.
All that is going to have a penalty in performace, but that's unavoidable. The defaults values are soft on performance but are not really intented for proper simulation of small and fast-moving objects.
Solution 3
How about set the Collision Detection of rigidbody to Continuous or Continuous Dynamic?
http://unity3d.com/support/documentation/Components/class-Rigidbody.html
Solution 4
Edit ---> Project Settings ---> Time ... decrease "Fixed Timestep" value .. This will solve the problem but it can affect performance negatively.
Another solution is could be calculate the coordinates (for example, you have a ball and wall. Ball will hit to wall. So calculate coordinates of wall and set hitting process according these cordinates )
Solution 5
Old Question but maybe it helps someone.
Go to Project settings > Time and Try dividing the fixed timestep and maximum allowed timestep by two or by four.
I had the problem that my player was able to squeeze through openings smaller than the players collider and that solved it. It also helps with stopping fast moving objects.
![CLo](https://i.stack.imgur.com/Tljzf.jpg?s=256&g=1)
Comments
-
CLo almost 2 years
I am having trouble keeping game objects inside of a contained space. When they reach the edge, there is some momentary push back but then they will go right through the wall.
I am using a Box Collider on the player, and a Mesh Collider for the level's wall. I am having issues with both a Player Character (a space ship) that the movement is controlled by the player. And with projectiles, which are fire and forget moving at a constant speed.
This is my movement code for my player. It is being run in the
FixedUpdate()
function.//Movement haxis = Input.GetAxis("Horizontal") * speed; vaxis = Input.GetAxis("Vertical") * speed; moveVector.x = haxis; moveVector.z = vaxis; if(moveVector.magnitude > 1) { moveVector.Normalize(); } rigidbody.MovePosition(transform.position + moveVector * speed);
With the bullets, they are given a velocity and the engine calculates their moviements. They are using Box Collider and it is set as a Trigger so they don't have physics. But I use
OnTriggerEnter
to destroy them.//Projectiles without physics collisiions function OnTriggerEnter (other : Collider) { Destroy(gameObject); }
Some, but not all of the bullets will be destroyed when hitting the mesh collider wall. The player will sometimes hit it and stop, but can usually push through it. How can I make the collisions with the mesh collider work every time?
-
CLo over 12 yearsI'm pretty sure that mesh colliders can't be set to Continuous if they are more than a certain number of tris. And even so, setting Continuous / Continuous Dynamic on the characters / bullets and even the meshes didn't work.
-
CLo over 12 yearsSubmitted an edit, but it should be Ray(lastPosition, direction) otherwise you may be inside the mesh collider and the Ray won't hit from inside of a collider. Looks like a good approach, I'll check it out.
-
CLo over 12 yearsThe only problem I can think of here is that we could be looking at a lot of moving elements and I suspect doing Raycast on all of them will be heavier on performance than using the compound colliders. If I get a chance to test this out I'll let you know what the performance difference is.
-
Petrucio over 12 yearscollider.Raycast checks against a single collider - I edited to Physics.Raycast. Regarding performance, I don't think it will have a big hit, but it needs testing. You cam use the layerMask parameter of Physics.Raycast to ensure it only gets tested against what you want it to (see the docs).
-
AlfredoVR over 12 yearsRaycasting is the way to go, because a lot of theoretical stuff that i can't fit in a comment, but this is the answer.
-
CLo over 12 yearsThanks @Fabio'Petrucio'Stange this answers the question very well. Though further along with my project, I need the physics info from a collision (some complex obstacles that will actually hit/damage the player based on the collision data). For this the compound colliders are doing the job quite well, I don't expect the Raycast to give me as much data.
-
Crazy Developer almost 11 yearsHi, I am not able to find the DontGoThroughtThings scripte Can you provide it. may be user has remove from above link.
-
Crazy Developer almost 11 yearsI found link for the DontGoThroughtThings Scripte code.google.com/p/lava-in-antarctica/source/browse/trunk/…
-
Kunalxigxag about 9 yearsAm using Unity 5 and after reading this, though I couldn't find 'Min Penetration for Penalty' but I tried changing the 'default contact offset' to 1. Now, fast moving objects are getting detected :)
-
Taranasus over 8 yearsYou sir, are my new God! THANK YOU!
-
nipponese over 6 years
Collision Detection: Dynamic
worked for me. Using Unity 2017. -
Ramon Dias over 3 yearswhy not use mesh colliders?
-
Simran Singh over 3 yearsMesh collider are hard to process, more mesh means more usage of processor, this questions is old so, at that time it was harder for mesh to process on cheap phones, specially android phones.
-
ghanbari about 3 yearsYou can use
Rigidbody.maxDepenetrationVelocity
for big objects that moving fast. -
CLo about 3 years@ghanbari might be worth writing up a new answer. This is a 5 year old question, so an updated answer would be helpful.