void OnCollisionEnter(Collision collision) { if (FracturedObjectSource == null || collision == null) { return; } if (collision.contacts == null) { return; } if (collision.contacts.Length == 0) { return; } if (collision.gameObject) { FracturedChunk otherChunk = collision.gameObject.GetComponent <FracturedChunk>(); if (otherChunk) { if (otherChunk.rigidbody.isKinematic && IsDetachedChunk == false) { // Just intersecting with other chunk in kinematic state return; } } } float fMass = Mathf.Infinity; // If there is no rigidbody we consider it static if (collision.rigidbody) { fMass = collision.rigidbody.mass; } if (IsDetachedChunk == false) { // Chunk still attached. // We are going to check if the collision is against a free chunk of the same object. This way we prevent chunks pushing each other out, we want to control // this only through the FractureObject.InterconnectionStrength variable bool bOtherIsFreeChunkFromSameObject = false; FracturedChunk otherChunk = collision.gameObject.GetComponent <FracturedChunk>(); if (otherChunk != null) { if (otherChunk.IsDetachedChunk == true && otherChunk.FracturedObjectSource == FracturedObjectSource) { bOtherIsFreeChunkFromSameObject = true; } } if (bOtherIsFreeChunkFromSameObject == false && collision.relativeVelocity.magnitude > FracturedObjectSource.EventDetachMinVelocity && fMass > FracturedObjectSource.EventDetachMinMass && rigidbody != null && IsDestructibleChunk()) { CollisionInfo collisionInfo = new CollisionInfo(this, collision, true); FracturedObjectSource.NotifyDetachChunkCollision(collisionInfo); if (collisionInfo.bCancelCollisionEvent == false) { List <FracturedChunk> listBreaks = new List <FracturedChunk>(); // Impact enough to make it detach. Compute random list of connected chunks that are detaching as well (we'll use the ConnectionStrength parameter). listBreaks = ComputeRandomConnectionBreaks(); listBreaks.Add(this); DetachFromObject(); foreach (FracturedChunk chunk in listBreaks) { collisionInfo.chunk = chunk; collisionInfo.bIsMain = false; collisionInfo.bCancelCollisionEvent = false; if (chunk != this) { FracturedObjectSource.NotifyDetachChunkCollision(collisionInfo); } if (collisionInfo.bCancelCollisionEvent == false) { chunk.DetachFromObject(); chunk.rigidbody.AddExplosionForce(collision.relativeVelocity.magnitude * FracturedObjectSource.EventDetachExitForce, collision.contacts[0].point, 0.0f, FracturedObjectSource.EventDetachUpwardsModifier); } } } } } else { // Free chunk if (collision.relativeVelocity.magnitude > FracturedObjectSource.EventDetachedMinVelocity && fMass > FracturedObjectSource.EventDetachedMinMass) { FracturedObjectSource.NotifyFreeChunkCollision(new CollisionInfo(this, collision, true)); } } }
void HandleCollision(Collider other, Vector3 v3CollisionPos, float relativeSpeed) { if (FracturedObjectSource == null || other == null) { return; } if (other.gameObject) { FracturedChunk otherChunk = other.gameObject.GetComponent <FracturedChunk>(); if (otherChunk && (other.attachedRigidbody != null)) { if (other.attachedRigidbody.isKinematic && IsDetachedChunk == false) { // Just intersecting with other chunk in kinematic state return; } } } float fMass = Mathf.Infinity; // If there is no rigidbody we consider it static Rigidbody otherRigidbody = other.attachedRigidbody; if (otherRigidbody != null) { fMass = otherRigidbody.mass; } if (IsDetachedChunk == false) { // Chunk still attached. // We are going to check if the collision is against a free chunk of the same object. This way we prevent chunks pushing each other out, we want to control // this only through the FractureObject.InterconnectionStrength variable bool bOtherIsFreeChunkFromSameObject = false; FracturedChunk otherChunk = other.gameObject.GetComponent <FracturedChunk>(); if (otherChunk != null) { if (otherChunk.IsDetachedChunk == true && otherChunk.FracturedObjectSource == FracturedObjectSource) { bOtherIsFreeChunkFromSameObject = true; } } if (bOtherIsFreeChunkFromSameObject == false && relativeSpeed > FracturedObjectSource.EventDetachMinVelocity && fMass > FracturedObjectSource.EventDetachMinMass && (GetComponent <Collider>() != null && GetComponent <Collider>().attachedRigidbody) && IsDestructibleChunk()) { CollisionInfo collisionInfo = new CollisionInfo(this, v3CollisionPos, true); FracturedObjectSource.NotifyDetachChunkCollision(collisionInfo); if (collisionInfo.bCancelCollisionEvent == false) { List <FracturedChunk> listBreaks = new List <FracturedChunk>(); // Impact enough to make it detach. Compute random list of connected chunks that are detaching as well (we'll use the ConnectionStrength parameter). listBreaks = ComputeRandomConnectionBreaks(); listBreaks.Add(this); DetachFromObject(); foreach (FracturedChunk chunk in listBreaks) { collisionInfo.chunk = chunk; collisionInfo.bIsMain = false; collisionInfo.bCancelCollisionEvent = false; if (chunk != this) { FracturedObjectSource.NotifyDetachChunkCollision(collisionInfo); } if (collisionInfo.bCancelCollisionEvent == false) { chunk.DetachFromObject(); chunk.GetComponent <Collider>().attachedRigidbody.AddExplosionForce(relativeSpeed * FracturedObjectSource.EventDetachExitForce, otherRigidbody.transform.position, 0.0f, FracturedObjectSource.EventDetachUpwardsModifier); } } } } } else { // Free chunk Rigidbody myRigidbody = GetComponent <Collider>().attachedRigidbody; Vector3 otherVelocity = otherRigidbody != null ? otherRigidbody.velocity : Vector3.zero; float relativeSpeedFree = (otherVelocity - myRigidbody.velocity).magnitude; if (relativeSpeedFree > FracturedObjectSource.EventDetachedMinVelocity && fMass > FracturedObjectSource.EventDetachedMinMass) { FracturedObjectSource.NotifyFreeChunkCollision(new CollisionInfo(this, v3CollisionPos, true)); } } }