using System; using System.Collections; using BlueWaterProject; using Sirenix.OdinInspector; using UnityEngine; // ReSharper disable once CheckNamespace namespace RhinocerosSkill { public class SeismicThrust : BaseSkill { [Title("추가 옵션")] [SerializeField] private bool isDrawingGizmo = true; [SerializeField] private float width = 3f; [SerializeField] private GameObject earthquakeParticlePrefab; private Transform particleInstantiateLocation; private Vector3 startPosition; private Vector3 halfScale; private RaycastHit[] hits; private bool isUsingSkill; 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; } protected override void BasicSetting() { base.BasicSetting(); hits = new RaycastHit[5]; } public override bool EnableSkill() { if (!enableSkill) return false; var targetDistance = Vector3.Distance(SkillInputData.Transform.position, SkillInputData.TargetCollider.transform.position); return targetDistance <= SkillData.Range; } public override void ActivateSkill(params Action[] actions) { enableSkill = false; StartCoroutine(SkillCoroutine(actions)); } private IEnumerator SkillCoroutine(params Action[] actions) { isUsingSkill = true; transform.position = SkillInputData.Transform.position; var angle = Mathf.Atan2(SkillInputData.PreviousDirection.x, SkillInputData.PreviousDirection.z) * Mathf.Rad2Deg; transform.rotation = Quaternion.Euler(0, angle, 0); transform.localScale = new Vector3(width, 6f, SkillData.Range * 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; } particleInstantiateLocation ??= FindAnyObjectByType().ParticleInstantiateLocation; Instantiate(earthquakeParticlePrefab, transform.position + transform.forward * 4f, transform.rotation, particleInstantiateLocation); startPosition = transform.position + transform.forward * halfScale.z; var maxSize = Physics.BoxCastNonAlloc(startPosition, halfScale, transform.forward, hits, transform.rotation, 0f, SkillInputData.TargetLayer, QueryTriggerInteraction.Ignore); for (var i = 0; i < maxSize; i++) { var iDamageable = hits[i].transform.GetComponent(); iDamageable?.TakeDamage(SkillData.Damage); var combatStatus = hits[i].transform.GetComponent(); if (combatStatus != null) { combatStatus.Stun(0.15f); combatStatus.SlowMoveSpeed(5f, 0.5f); combatStatus.GetComponent().AddForce(transform.forward * 20f, ForceMode.Impulse); } } HideIndicator(); EndSkill(SkillData.Cooldown, actions[0]); } private void EndSkill(float cooldown, Action action) { StartCoroutine(Utils.CoolDown(cooldown, () => enableSkill = true)); action?.Invoke(); } } }