public void Explode(Vector3 v3ExplosionPosition, float fExplosionForce, float fRadius, bool bPlayExplosionSound, bool bInstanceExplosionPrefabs, bool bAlsoExplodeFree, bool bCheckStructureIntegrityAfter)
    {
        // Explodes only chunks in a given radius

        List <FracturedChunk> listChunksAffected = new List <FracturedChunk>();

        // Play sound

        if (EventExplosionSound && bPlayExplosionSound)
        {
            AudioSource.PlayClipAtPoint(EventExplosionSound, v3ExplosionPosition);
        }

        // Explode chunks in range

        foreach (FracturedChunk chunk in GetDestructibleChunksInRadius(v3ExplosionPosition, fRadius, bAlsoExplodeFree))
        {
            if (chunk)
            {
                chunk.DetachFromObject(false);
                chunk.GetComponent <Rigidbody>().AddExplosionForce(fExplosionForce, v3ExplosionPosition, 0.0f, 0.0f);
                listChunksAffected.Add(chunk);
            }
        }

        // Instance prefabs on random positions

        if (bInstanceExplosionPrefabs && EventExplosionPrefabsArray.Length > 0 && EventExplosionPrefabsInstanceCount > 0 && listChunksAffected.Count > 0)
        {
            for (int i = 0; i < Mathf.Max(EventExplosionPrefabsInstanceCount, listChunksAffected.Count); i++)
            {
                FracturedObject.PrefabInfo prefab = EventExplosionPrefabsArray[UnityEngine.Random.Range(0, EventExplosionPrefabsArray.Length)];

                if (prefab != null)
                {
                    GameObject newGameObject = Instantiate(prefab.GameObject, listChunksAffected[UnityEngine.Random.Range(0, listChunksAffected.Count)].transform.position, prefab.GameObject.transform.rotation) as GameObject;

                    if (Mathf.Approximately(prefab.MinLifeTime, 0.0f) == false || Mathf.Approximately(prefab.MaxLifeTime, 0.0f) == false)
                    {
                        DieTimer timer = newGameObject.AddComponent <DieTimer>();
                        timer.SecondsToDie = UnityEngine.Random.Range(prefab.MinLifeTime, prefab.MaxLifeTime);
                    }
                }
            }
        }

        if (bCheckStructureIntegrityAfter)
        {
            CheckDetachNonSupportedChunks();
        }
    }
    public void NotifyFreeChunkCollision(FracturedChunk.CollisionInfo collisionInfo)
    {
        if (EventDetachedCollisionCallGameObject != null && EventDetachedCollisionCallMethod.Length > 0)
        {
            EventDetachedCollisionCallGameObject.SendMessage(EventDetachedCollisionCallMethod, collisionInfo);
        }

        if (collisionInfo.bCancelCollisionEvent == false)
        {
            if (EventDetachedSoundArray.Length > 0)
            {
                int nFreeSound = -1;

                for (int nSound = 0; nSound < m_afFreeChunkSoundTimers.Length; nSound++)
                {
                    if (m_afFreeChunkSoundTimers[nSound] <= 0.0f)
                    {
                        nFreeSound = nSound;
                        break;
                    }
                }

                if (nFreeSound != -1)
                {
                    AudioClip clip = EventDetachedSoundArray[UnityEngine.Random.Range(0, EventDetachedSoundArray.Length)];

                    if (clip != null)
                    {
                        AudioSource.PlayClipAtPoint(clip, collisionInfo.collisionPoint);
                    }

                    m_afFreeChunkSoundTimers[nFreeSound] = clip.length;
                }
            }

            if (EventDetachedPrefabsArray.Length > 0)
            {
                FracturedObject.PrefabInfo prefab = EventDetachedPrefabsArray[UnityEngine.Random.Range(0, EventDetachedPrefabsArray.Length)];

                if (prefab != null)
                {
                    int nFreePrefab = -1;

                    for (int nPrefab = 0; nPrefab < m_afFreeChunkPrefabTimers.Length; nPrefab++)
                    {
                        if (m_afFreeChunkPrefabTimers[nPrefab] <= 0.0f)
                        {
                            nFreePrefab = nPrefab;
                            break;
                        }
                    }

                    if (nFreePrefab != -1)
                    {
                        GameObject newGameObject = Instantiate(prefab.GameObject, collisionInfo.collisionPoint, prefab.GameObject.transform.rotation) as GameObject;

                        if (Mathf.Approximately(prefab.MinLifeTime, 0.0f) == false || Mathf.Approximately(prefab.MaxLifeTime, 0.0f) == false)
                        {
                            DieTimer timer = newGameObject.AddComponent <DieTimer>();
                            timer.SecondsToDie = UnityEngine.Random.Range(prefab.MinLifeTime, prefab.MaxLifeTime);

                            m_afFreeChunkPrefabTimers[nFreePrefab] = timer.SecondsToDie;
                        }
                        else
                        {
                            m_afFreeChunkPrefabTimers[nFreePrefab] = float.MaxValue;
                        }
                    }
                }
            }
        }
    }
    public void Explode(Vector3 v3ExplosionPosition, float fExplosionForce)
    {
        // Explodes all chunks

        if (m_bExploded == true)
        {
            return;
        }

        // Play sound

        if (EventExplosionSound)
        {
            AudioSource.PlayClipAtPoint(EventExplosionSound, v3ExplosionPosition);
        }

        // Instance prefabs on random positions

        if (EventExplosionPrefabsArray.Length > 0 && EventExplosionPrefabsInstanceCount > 0 && ListFracturedChunks.Count > 0)
        {
            for (int i = 0; i < EventExplosionPrefabsInstanceCount; i++)
            {
                FracturedObject.PrefabInfo prefab = EventExplosionPrefabsArray[UnityEngine.Random.Range(0, EventExplosionPrefabsArray.Length)];

                if (prefab != null)
                {
                    FracturedChunk chunkRandom = null;

                    while (chunkRandom == null)
                    {
                        chunkRandom = ListFracturedChunks[UnityEngine.Random.Range(0, ListFracturedChunks.Count)];
                    }

                    GameObject newGameObject = Instantiate(prefab.GameObject, chunkRandom.transform.position, prefab.GameObject.transform.rotation) as GameObject;

                    if (Mathf.Approximately(prefab.MinLifeTime, 0.0f) == false || Mathf.Approximately(prefab.MaxLifeTime, 0.0f) == false)
                    {
                        DieTimer timer = newGameObject.AddComponent <DieTimer>();
                        timer.SecondsToDie = UnityEngine.Random.Range(prefab.MinLifeTime, prefab.MaxLifeTime);
                    }
                }
            }
        }

        // Explode chunks

        foreach (FracturedChunk chunk in ListFracturedChunks)
        {
            if (chunk)
            {
                chunk.ListAdjacentChunks.Clear();

                if (chunk.IsDestructibleChunk() && chunk.IsDetachedChunk == false)
                {
                    chunk.DetachFromObject(false);
                    chunk.GetComponent <Rigidbody>().AddExplosionForce(fExplosionForce, v3ExplosionPosition, 0.0f, 0.0f);
                }
            }
        }

        m_bExploded = true;
    }