using System; using System.Collections; using BlueWater.Interfaces; using BlueWater.Maps; using BlueWater.Utility; using Sirenix.OdinInspector; using UnityEngine; namespace BlueWater.Enemies.Bosses.Rhinoceros.Skills { public class SeismicThrust : BaseSkill { [Title("추가 옵션")] [SerializeField] private bool _isDrawingGizmo = true; private SeismicThrustData _seismicThrustData; private Rhinoceros _rhinoceros; private Collider _targetCollider; private LayerMask _targetLayer; private Transform _particleInstantiateLocation; private GameObject _seismicThrustParticle; private Vector3 _startPosition; private Vector3 _halfScale; private void OnDrawGizmos() { if (!_isDrawingGizmo || ! IsUsingSkill) return; Gizmos.color = Color.red; Gizmos.matrix = Matrix4x4.TRS(_startPosition, transform.rotation, Vector3.one); Gizmos.DrawWireCube(Vector3.zero, _halfScale * 2f); Gizmos.matrix = Matrix4x4.identity; } private void OnDestroy() { if (_seismicThrustParticle) { Destroy(gameObject); } } protected override void BasicSetting() { if (!_rhinoceros) { _rhinoceros = SkillUser.GetComponent(); _targetCollider = _rhinoceros.Target; _targetLayer = _rhinoceros.TargetLayer; _particleInstantiateLocation = _rhinoceros.BossMapController.ParticleInstantiateLocation; } _seismicThrustData = (SeismicThrustData)SkillData; RaycastHits = new RaycastHit[4]; base.BasicSetting(); } public override bool CanSkill() { if (!EnableSkill) return false; var targetDistance = Vector3.Distance(SkillUser.transform.position,_targetCollider.transform.position); return targetDistance <= SkillData.Radius; } public override void ActivateSkill(params Action[] actions) { Utils.StartUniqueCoroutine(this, ref SkillCoroutineInstance, SkillCoroutine(actions)); } private IEnumerator SkillCoroutine(params Action[] actions) { EnableSkill = false; IsUsingSkill = true; transform.position = SkillUser.transform.position + Vector3.up * 3f; var angle = Mathf.Atan2(_rhinoceros.CurrentDirection.x, _rhinoceros.CurrentDirection.z) * Mathf.Rad2Deg; transform.rotation = Quaternion.Euler(0, angle, 0); transform.localScale = new Vector3(_seismicThrustData.HorizontalRange, 6f, SkillData.Radius * 2); var myLocalScale = transform.localScale; _halfScale = new Vector3(myLocalScale.x * 0.5f, myLocalScale.y * 0.5f, myLocalScale.z * 0.25f); 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; } _seismicThrustParticle = Instantiate(_seismicThrustData.SeismicThrustParticle, SkillUser.transform.position + transform.forward * 4f, transform.rotation, _particleInstantiateLocation); _startPosition = SkillUser.transform.position + transform.forward * _halfScale.z; var maxSize = Physics.BoxCastNonAlloc(_startPosition, _halfScale, transform.forward, RaycastHits, transform.rotation, 0f, _targetLayer, QueryTriggerInteraction.Collide); for (var i = 0; i < maxSize; i++) { var raycastHit = RaycastHits[i]; var iDamageable = raycastHit.transform.GetComponentInParent(); if (iDamageable == null || !iDamageable.CanDamage()) continue; iDamageable.TakeDamage(SkillData.Damage); var iStunnable = raycastHit.transform.GetComponentInParent(); iStunnable?.Stun(_seismicThrustData.StunDuration); var iSlowable = raycastHit.transform.GetComponentInParent(); iSlowable?.SlowMoveSpeed(_seismicThrustData.SlowDuration, _seismicThrustData.SlowCoefficient); var iPhysicMovable = raycastHit.transform.GetComponentInParent(); iPhysicMovable?.AddForce(transform.forward * _seismicThrustData.PushPower, ForceMode.Impulse); } HideIndicator(); EndSkill(SkillData.Cooldown, actions[0]); } private void EndSkill(float cooldown, Action action) { Utils.EndUniqueCoroutine(this, ref SkillCoroutineInstance); action?.Invoke(); Utils.StartUniqueCoroutine(this, ref CooldownCoroutineInstance,Utils.CoolDownCoroutine(cooldown, EndCooldown)); } } }