Exemple #1
0
    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));
            }
        }
    }
Exemple #2
0
    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));
            }
        }
    }