- Home /
Collider collides, triggers OnCollisionEnter, then bounces, before destroying itself
essentially i have a OnCollisionEnter function call Destroy on the object, yet the object is hitting and bouncing off of the collider it's calling the OnCollisionEnter on... shouldn't it be calling that as soon as it knows its going to bounce.. and destroying itself before it has a chance to bounce away?
looking for a fix to this, before I am forced to switch over to ray/spherecasting
Can you post the code here that you're currently using?
it's just the stock code from the ulink SnowBox demo, if you have that project you can see the whole spectrum of the issue. It bounces off of anything it collides with before being destroyed a milisecond later. I did debug.log(Time.time) in the first line of the OnTriggerEnter() and OnCollisionEnter() and in OnDestroy() and the times match up, so that proved that the moment it gets the message, the ball has already hit the collider and bounced off of it before sending the OnCollisionEnter....
Answer by iamsteele · Jul 17, 2014 at 01:19 PM
After posting this question, further research lead me to many questions about the same thing, but the one that clearly states my question is this, and as such, I will implement my own code to detect the collision before it happens... because OnCollisionEnter is called a frame later than it "should" be.
http://answers.unity3d.com/questions/320069/oncollisionenter-before-physic-simulations.html
EDIT: here's the code I implemented, basically a refactoring of the DontGoThroughThis.cs on the wiki.
//variables for raycasting in fixed updated private float minimumExtent; //private float partialExtent; private float sqrMinimumExtent; private Rigidbody myRigidbody;
//optimized declarations for fixedupdate
private float movementSqrMagnitude;
private Vector3 movementNextStep;
private float movementMagnitude;
private RaycastHit hitInfo;
Vector3 currentPosition = new Vector3();
Vector3 newPosition = new Vector3();
Vector3 nextPosition = new Vector3();
//initialize values
void Awake()
{
myRigidbody = rigidbody;
minimumExtent = Mathf.Min(Mathf.Min(collider.bounds.extents.x, collider.bounds.extents.y), collider.bounds.extents.z);
//partialExtent = minimumExtent * (1.0f - skinWidth);
sqrMinimumExtent = minimumExtent * minimumExtent;
myRigidbody.velocity = transform.forward * SPEED;
myRigidbody.angularVelocity = new Vector3(SPIN, SPIN, SPIN);
Destroy(gameObject, timeToLive);
}
void FixedUpdate()
{
//have we moved more than our minimum extent?
currentPosition = myRigidbody.position;
newPosition.x = currentPosition.x + myRigidbody.velocity.x * Time.deltaTime;
newPosition.y = currentPosition.y + myRigidbody.velocity.y * Time.deltaTime - 0.5f * -9.81f * Time.deltaTime * Time.deltaTime;
newPosition.z = currentPosition.z + myRigidbody.velocity.z * Time.deltaTime;
//newVelocity.y = oldVelocity.y - gravity * timeDelta;
nextPosition.x = newPosition.x + myRigidbody.velocity.x * Time.deltaTime;
nextPosition.y = newPosition.y + myRigidbody.velocity.y * Time.deltaTime - 0.5f * -9.81f * Time.deltaTime * Time.deltaTime;
nextPosition.z = newPosition.z + myRigidbody.velocity.z * Time.deltaTime;
//nextVelocity.y = newVelocity.y - gravity * timeDelta;
movementNextStep = nextPosition - newPosition;
movementSqrMagnitude = (nextPosition - currentPosition).sqrMagnitude;
if (movementSqrMagnitude > sqrMinimumExtent)
{
movementMagnitude = Mathf.Sqrt(movementSqrMagnitude);
//check for obstructions we will have hit
//Debug.DrawLine (currentPosition, nextPosition);
if (Physics.Raycast(currentPosition, movementNextStep, out hitInfo, movementMagnitude, layerMask.value)) {
CustomOnCollisionEnter(hitInfo.collider);
}
}
}
//For visual affects only. Actual collisions are calculated on the server.
void CustomOnCollisionEnter(Collider colliderInfo)
{
//Debug.Log ("CustomCollisionEnter hit at "+Time.time+" with"+colliderInfo.name);
if (hitSplatter != null) {
Instantiate (hitSplatter, transform.position, Quaternion.identity);
Destroy (gameObject);
}
}
Answer by malu · Jul 17, 2014 at 09:10 AM
You can set the rigidbody kinematic to true for the object that just entered the trigger. Maybe you have to tweak your trigger area for this.
Thanks for the reply, but this question more pertains to the fact that I have physics ti$$anonymous$$g issues where the OnCollisionEnter method is called AFTER the physics engine detects a collision and steps the ball through the steps of bouncing off the target it hit and moving forward as far as it would during the normal physics step.
Your answer
Follow this Question
Related Questions
How to get OnCollisionEnter working with Terrain. JavaScript 2 Answers
2D 360 degress platformer example needed 0 Answers
Optimizing C# Code and physics 2 Answers
Fungus C# ExecuteBlock() won't execute when triggered by collision or trigger enter…! 0 Answers
Location of RigidBody2D on collision 3 Answers