using System; using System.Collections; using BlueWater.Audios; using BlueWater.Interfaces; using BlueWater.Utility; using Sirenix.OdinInspector; using UnityEngine; namespace BlueWater.Enemies.Bosses.Rhinoceros.Skills { public class HammerSlam : BaseSkill { [Title("추가 옵션")] [SerializeField] private bool _isDrawingGizmo = true; private HammerSlamData _hammerSlamData; private Rhinoceros _rhinoceros; private AnimationController _animationController; private Collider _targetCollider; private Vector3 _attackStartPosition; private void OnDrawGizmos() { if (!_isDrawingGizmo || !IsUsingSkill) return; Gizmos.color = Color.red; Gizmos.DrawWireSphere(_attackStartPosition, SkillData.Radius); } protected override void BasicSetting() { if (!_rhinoceros) { _rhinoceros = SkillUser.GetComponent(); _animationController = _rhinoceros.AnimationController; _targetCollider = _rhinoceros.Target; } _hammerSlamData = (HammerSlamData)SkillData; HitColliders = new Collider[5]; base.BasicSetting(); } public override bool CanSkill() { if (!EnableSkill) return false; var targetDistance = Vector3.Distance(SkillUser.transform.position,_targetCollider.transform.position); return targetDistance <= SkillData.Radius + _hammerSlamData.AttackOffset; } public override void ActivateSkill(params Action[] actions) { Utils.StartUniqueCoroutine(this, ref SkillCoroutineInstance, SkillCoroutine(actions)); } private IEnumerator SkillCoroutine(params Action[] actions) { EnableSkill = false; _rhinoceros.StopMove(); _animationController.SetAnimationParameter("skillIndex", (int)RhinocerosSkill.HammerSlam); var animationStarted = false; yield return StartCoroutine(_animationController.WaitForAnimationToRun("HammerSlam", success => animationStarted = success)); if (!animationStarted) { EndSkill(0, actions[0]); yield break; } IsUsingSkill = true; var userStartPosition = SkillUser.transform.position; var targetPosition = _targetCollider.transform.position; var targetVector = targetPosition - userStartPosition; targetVector.y = 0f; var targetDirection = targetVector.normalized; _rhinoceros.CurrentDirection = targetDirection; _attackStartPosition = userStartPosition + targetDirection * _hammerSlamData.AttackOffset; transform.position = _attackStartPosition + Vector3.up * SkillData.Radius; transform.localScale = Vector3.one * (SkillData.Radius * 2f); ShowIndicator(); var elapsedTime = 0f; var fill = 1 / SkillData.CastingTime; while (elapsedTime <= SkillData.CastingTime) { elapsedTime += Time.deltaTime; if (IsUsingIndicator && Indicator) { var fillValue = Indicator.material.GetFloat(_fillHash) + Time.deltaTime * fill; Indicator.material.SetFloat(_fillHash, fillValue); } yield return null; } AudioManager.Instance.PlaySfx("HammerSlam"); var hitCount = Physics.OverlapSphereNonAlloc(_attackStartPosition, SkillData.Radius, HitColliders, _hammerSlamData.TargetLayer, QueryTriggerInteraction.Collide); for (var i = 0; i < hitCount; i++) { var hitCollider = HitColliders[i]; var iDamageable = hitCollider.GetComponentInParent(); if (iDamageable == null || !iDamageable.CanDamage()) continue; iDamageable.TakeDamage(SkillData.Damage); var iStunnable = hitCollider.transform.GetComponentInParent(); iStunnable?.TryStun(_hammerSlamData.StunDuration); var iPhysicMovable = hitCollider.GetComponentInParent(); if (iPhysicMovable == null) continue; var hitVector = hitCollider.transform.position - SkillUser.transform.position; hitVector.y = 0f; var hitDirection = hitVector.normalized; iPhysicMovable.SetPush(hitDirection, _hammerSlamData.PushPower); } HideIndicator(); while (_animationController.IsComparingCurrentAnimation("HammerSlam") && _animationController.GetCurrentAnimationNormalizedTime() <= 1f) { yield return null; } EndSkill(SkillData.Cooldown, actions[0]); } private void EndSkill(float cooldown, Action action) { Utils.EndUniqueCoroutine(this, ref SkillCoroutineInstance); _animationController.SetAnimationParameter("skillIndex", (int)RhinocerosSkill.None); action?.Invoke(); IsUsingSkill = false; Utils.StartUniqueCoroutine(this, ref CooldownCoroutineInstance,Utils.CoolDownCoroutine(cooldown, EndCooldown)); } } }