- Home /
High speed Object Collisionhow to avoid pass through collider object?
I give rigidbody to the object, and use rigidbody.AddForce to make the object moved. Some times, the speed will be very high, and the object may pass through some other collider objects. How can I avoid this?? Thank you for help??
also: rigidbody.interpolation = RigidbodyInterpolation.Interpolate;
Answer by anonymous 1 · Feb 25, 2011 at 12:30 AM
From the official Unity Script Reference (with a few spelling corrections):
"Use the Rigidbody.collisionDetectionMode property to set up a Rigidbody for continuous collision detection, which is used to prevent fast moving objects from passing through other objects without detecting collisions. For best results, set this value to CollisionDetectionMode.ContinuousDynamic for fast moving objects, and for other objects which these need to collide with, set it to CollisionDetectionMode.Continuous. This has a big impact on physics performance, so just leave it set to the default value of CollisionDetectionMode.Discrete, if you don't have any issues with collisions of fast objects. Continuous Collision Detection is only supported for Rigidbodies with Sphere-, Capsule- or BoxColliders."
http://unity3d.com/support/documentation/ScriptReference/Rigidbody-collisionDetectionMode.html
Thx, bro, saved my day. Just in case, one can find this drop-down in GUI of "Rigidbody" component, it is called "Collision Detection" there.
Thanks so much. Looks like it's working for me, after messing with a lot of permutations.
Answer by PrimeDerektive · Jan 10, 2011 at 03:15 PM
See the DontGoThroughThings script on the community wiki.
This is a very elegant solution. For more about it: http://answers.unity3d.com/questions/49252/cheapest-way-to-catch-collisions-on-very-fast-moving-objects/49259#49259
I would point out that this is a flaky solution - due to the use of the physics ray cast it only works some of the time (probably most of the time in most cases) because it is using a raycast... even raycasting from an even volume of points in a loop is not robust in this case.
It is a shame there is no option to use sane physics in Unity - swept volumes are a well known and robust solution to this ancient and well understood problem. I'm guessing PhysX is too geared towards performance to want to provide this - or it is not exposed in Unity.
Is there a Rigidbody2D version of this? Rigidbody2Ds don't have a position property, so it won't compile if you try to replace Rigidbody with Rigidbody2D in the script.
Hi, the link is dead. Does anyone have a copy they can add into the answer?
Here is a new link to it. http://wiki.unity3d.com/index.php?title=DontGoThroughThings
And here's the C# code.
// Script from $$anonymous$$ Brauer, Adrian
// http://wiki.unity3d.com/index.php?title=DontGoThroughThings
using UnityEngine;
public class DontGoThroughThings : $$anonymous$$onoBehaviour
{
// Careful when setting this to true - it might cause double
// events to be fired - but it won't pass through the trigger
public bool sendTrigger$$anonymous$$essage = false;
public Layer$$anonymous$$ask layer$$anonymous$$ask = -1; //make sure we aren't in this layer
public float skinWidth = 0.1f; //probably doesn't need to be changed
private float $$anonymous$$imumExtent;
private float partialExtent;
private float sqr$$anonymous$$inimumExtent;
private Vector3 previousPosition;
private Rigidbody myRigidbody;
private Collider myCollider;
//initialize values
void Start()
{
myRigidbody = GetComponent<Rigidbody>();
myCollider = GetComponent<Collider>();
previousPosition = myRigidbody.position;
$$anonymous$$imumExtent = $$anonymous$$athf.$$anonymous$$in($$anonymous$$athf.$$anonymous$$in(myCollider.bounds.extents.x, myCollider.bounds.extents.y), myCollider.bounds.extents.z);
partialExtent = $$anonymous$$imumExtent * (1.0f - skinWidth);
sqr$$anonymous$$inimumExtent = $$anonymous$$imumExtent * $$anonymous$$imumExtent;
}
void FixedUpdate()
{
//have we moved more than our $$anonymous$$imum extent?
Vector3 movementThisStep = myRigidbody.position - previousPosition;
float movementSqr$$anonymous$$agnitude = movementThisStep.sqr$$anonymous$$agnitude;
if (movementSqr$$anonymous$$agnitude > sqr$$anonymous$$inimumExtent)
{
float movement$$anonymous$$agnitude = $$anonymous$$athf.Sqrt(movementSqr$$anonymous$$agnitude);
RaycastHit hitInfo;
//check for obstructions we might have missed
if (Physics.Raycast(previousPosition, movementThisStep, out hitInfo, movement$$anonymous$$agnitude, layer$$anonymous$$ask.value))
{
if (!hitInfo.collider)
return;
if (hitInfo.collider.isTrigger)
hitInfo.collider.Send$$anonymous$$essage("OnTriggerEnter", myCollider);
if (!hitInfo.collider.isTrigger)
myRigidbody.position = hitInfo.point - (movementThisStep / movement$$anonymous$$agnitude) * partialExtent;
}
}
previousPosition = myRigidbody.position;
}
}
Answer by ccx217 · Nov 09, 2015 at 12:58 PM
Change the rigidbody collision detection from "discrete" to "Continuous Dynamic". hope it helped :)
Thank you so much! this just instantly fixed a problem that's been bugging me for ages :)
Answer by Borgo · Jan 10, 2011 at 01:36 PM
You have 2 ways:
1: Speed up the physics time in the physics menu (see the documentation)
2: You can make a raycast to your moving object and stop the motion by script.
Bonus hint: Add a rigidbody component to the stoped object and mark it as "IsKinect". The colision between two rigidbody is very more realistic.
Good Look
just use the collision detection mode in the rigidbody component.
Answer by oliver-jones · Nov 18, 2010 at 02:01 AM
Make the collider of the object that is moving at high speed slightly larger than it is already until you find it doesn't pass through anymore.
Thanks. but it will not work when the speed is dynamic changed.
Sure it will - doesn't matter how fast your objects going - if you make your collider big enough it will not pass -- add an extra box collider to the object, and resize it bigger.
A bug in the engine I think. Or limitations? I'm working on golf simulation using RayCast had additional tests.
We can never know the biggest speed of the object. And also,if there are a lot of objects, if i changed one or more of the collider, the layer of the objects will changed too;
So we mush set a biggest speed the object can use;
Your answer
Follow this Question
Related Questions
How to avoid a gameobject inside another while they're in collision? 0 Answers
How do you make a plane not pass through anything? 2 Answers
Detecting which Collider involved in Trigger 'Collision' 4 Answers
box colliders with rigidbodies passing through each other 0 Answers
How to make an object enter a gui screen upon a collision? 1 Answer