using OctoberStudio.Extensions; using OctoberStudio.Pool; using System.Collections; using System.Collections.Generic; using UnityEngine; namespace OctoberStudio.Enemy { public class EnemyMaskBehavior : EnemyBehavior { private static readonly int IS_CHARING_BOOL = Animator.StringToHash("Is Charging"); [SerializeField] GameObject projectilePrefab; [SerializeField] GameObject handPrefab; [SerializeField] float attackCooldown = 3f; [SerializeField] int projectilesCount = 4; [SerializeField] Animator animator; [SerializeField] float handDamage; private PoolComponent projectilePool; private PoolComponent handPool; private List projectiles = new List(); private Coroutine attackCoroutine; protected override void Awake() { base.Awake(); projectilePool = new PoolComponent("Mask Enemy Projectile", projectilePrefab, projectilesCount * 3); handPool = new PoolComponent("Mask Enemy Hand", handPrefab, 6); } public override void Play() { base.Play(); attackCoroutine = StartCoroutine(BossBehavior()); } private IEnumerator BossBehavior() { while (IsAlive) { yield return new WaitForSeconds(attackCooldown); IsMoving = false; for (int i = 0; i < 3; i++) { var playerPosition = PlayerBehavior.Player.transform.position.XY(); Vector2 position = Vector2.zero; bool foundPosition = false; for (int j = 0; j < 20; j++) { position = playerPosition + Random.insideUnitCircle.normalized * 2; if(StageController.FieldManager.ValidatePosition(position, Vector2.one * 0.2f)) { foundPosition = true; break; } } if (foundPosition) { var hand = handPool.GetEntity(); hand.transform.position = position; hand.Damage = handDamage * StageController.Stage.EnemyDamage; var direction = (playerPosition - position).normalized; hand.Init(playerPosition + direction * 2f, 5); hand.onFinished += OnProjectileFinished; projectiles.Add(hand); } yield return new WaitForSeconds(0.7f); } IsMoving = true; yield return new WaitForSeconds(attackCooldown); IsMoving = false; animator.SetBool(IS_CHARING_BOOL, true); yield return new WaitForSeconds(attackCooldown); animator.SetBool(IS_CHARING_BOOL, false); IsMoving = true; } } public void WaveAttack() { var playerDirection = (PlayerBehavior.CenterPosition - transform.position.XY()).normalized; var attackRotation = Quaternion.FromToRotation(Vector2.up, playerDirection); var stepAngle = 360f / projectilesCount; for (int i = 0; i < projectilesCount; i++) { var rotation = attackRotation * Quaternion.Euler(0, 0, stepAngle * i); var direction = rotation * Vector2.up; var projectile = projectilePool.GetEntity(); projectile.Init(transform.position, direction); projectile.Damage = GetDamage(); projectile.onFinished += OnProjectileFinished; projectiles.Add(projectile); } } private void OnProjectileFinished(SimpleEnemyProjectileBehavior projectile) { projectile.onFinished -= OnProjectileFinished; projectiles.Remove(projectile); } protected override void Die(bool flash) { base.Die(flash); if (attackCoroutine != null) { StopCoroutine(attackCoroutine); attackCoroutine = null; } for(int i = 0; i < projectiles.Count; i++) { var projectile = projectiles[i]; projectile.onFinished -= OnProjectileFinished; projectile.Disable(); } projectiles.Clear(); projectilePool.Destroy(); handPool.Destroy(); } } }