コード例 #1
0
    // When destroying walls some colliders are left behind. Fix should be incoming:
    // https://github.com/Unity-Technologies/2d-extras/issues/34
    public void TriggerExplosion(Vector3 worldPosition, float worldRadius, bool damageWallsOnly = true, IEnemy explosionSource = null, bool damageSelf = true)
    {
        int tilesChecked = MapUtil.ClearCircle(this, mapStyle_, worldPosition, worldRadius);

        WallCompositeCollider.generationType = CompositeCollider2D.GenerationType.Manual;
        int tilesCleared = 0;

        for (int i = 0; i < tilesChecked; ++i)
        {
            bool wasDestroyed = MapUtil.LatestResultFlags[i];
            if (wasDestroyed)
            {
                tilesCleared++;
            }

            if (wasDestroyed || !damageWallsOnly)
            {
                var tile = MapUtil.LatestResultPositions[i];

                // Show effect a bit above wall tile center since they also have a top
                const float EffectOffset = 0.5f;
                var         tileWorldPos = WallTileMap.GetCellCenterWorld(tile) + Vector3.up * EffectOffset;
                ParticleScript.EmitAtPosition(SceneGlobals.Instance.ParticleScript.AnimatedFireParticles, tileWorldPos, 3);
            }
        }

        if (!damageWallsOnly)
        {
            var   player    = PlayableCharacters.GetPlayerInScene();
            var   playerPos = player.GetPosition();
            float playerDistanceFromExplosion = (worldPosition - playerPos).magnitude;
            bool  damagePlayer = playerDistanceFromExplosion < worldRadius * 0.8f;
            if (damagePlayer)
            {
                player.TakeDamage(explosionSource, CurrentRunData.Instance.PlayerExplosionDamage, Vector3.zero);
            }

            int mask  = SceneGlobals.Instance.EnemyDeadOrAliveMask;
            int count = Physics2D.OverlapCircleNonAlloc(worldPosition, worldRadius * 0.9f, TempColliderResult, mask);
            for (int i = 0; i < count; ++i)
            {
                var enemyGO = TempColliderResult[i];
                var enemy   = enemyGO.GetComponent <IEnemy>();

                bool isSelf = enemy == explosionSource;
                bool skipDueToSelfDamage = isSelf && !damageSelf;
                if (enemy != null && !skipDueToSelfDamage)
                {
                    var diff      = enemyGO.transform.position - worldPosition;
                    var direction = diff.normalized;
                    enemy.TakeDamage(ExplosionDamageToEnemies, direction * 1.5f);
                }
            }
        }

        SceneGlobals.Instance.AudioManager.PlaySfxClip(SceneGlobals.Instance.AudioManager.AudioClips.LargeExplosion1, 1, 0.1f);
        SceneGlobals.Instance.CameraShake.SetMinimumShake(1.0f);

        WallCompositeCollider.generationType = CompositeCollider2D.GenerationType.Synchronous;
        TilemapCollider.enabled = false;
        TilemapCollider.enabled = true;
    }