using System; using System.Collections; using BlueWaterProject; using Sirenix.OdinInspector; using UnityEngine; // ReSharper disable once CheckNamespace namespace RhinocerosSkill { public class LineRush : SkillBase { [Title("추가 옵션")] [SerializeField] private bool isDrawingGizmo = true; [SerializeField] private float width = 3f; [SerializeField] private float rushSpeed = 15f; [SerializeField] private float rushOffset = 3f; private bool isUsingSkill; private Vector3 startPosition; private float distanceToTarget; private Vector3 direction; private RaycastHit[] hits; private bool isAttacked; private void OnDrawGizmos() { if (!isDrawingGizmo || !isUsingSkill) return; if (SkillInputData.PlayerCollider is CapsuleCollider capsuleCollider) { var capsuleRadius = capsuleCollider.radius; var point1 = SkillInputData.PlayerRb.position + Vector3.up * capsuleRadius; Gizmos.color = Color.red; Gizmos.DrawWireSphere(point1, capsuleRadius); } } public override void ActivateSkill(params Action[] actions) { ReadySkill = false; SkillInputData.PlayerAnimator.SetBool("isLineRush", true); CoolDown(Cooldown, () => ReadySkill = true); StartCoroutine(SkillCoroutine(actions)); } public override bool EnableSkill() { if (!ReadySkill) return false; return true; } protected override void BasicSetting() { base.BasicSetting(); hits = new RaycastHit[5]; } private IEnumerator SkillCoroutine(params Action[] actions) { while (!SkillInputData.PlayerAnimator.GetCurrentAnimatorStateInfo(0).IsName("LineRush")) { yield return null; } isUsingSkill = true; isAttacked = false; startPosition = SkillInputData.PlayerRb.position; var vectorToTarget = SkillInputData.TargetCollider.transform.position - startPosition; vectorToTarget.y = 0f; direction = vectorToTarget.normalized; distanceToTarget = vectorToTarget.magnitude + rushOffset; transform.position = startPosition; transform.localScale = new Vector3(width, 6f, distanceToTarget * 2); var angle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg; transform.rotation = Quaternion.Euler(0, angle, 0); actions[1].Invoke(); ShowIndicator(); var elapsedTime = 0f; var fill = 1 / CastingTime; while (elapsedTime < CastingTime) { elapsedTime += Time.deltaTime; if (isUsingIndicator && indicator) { var fillValue = indicator.material.GetFloat(FillHash) + Time.deltaTime * fill; indicator.material.SetFloat(FillHash, fillValue); } yield return null; } HideIndicator(); SkillInputData.PlayerAgent.enabled = false; SkillInputData.PlayerRb.isKinematic = false; var timeToReachTarget = distanceToTarget / rushSpeed; elapsedTime = 0f; var capsuleCollider = (CapsuleCollider)SkillInputData.PlayerCollider; var capsuleRadius = capsuleCollider.radius; while (elapsedTime < timeToReachTarget) { SkillInputData.PlayerRb.velocity = direction * rushSpeed; elapsedTime += Time.deltaTime; var playerPosition = SkillInputData.PlayerRb.position; var point1 = playerPosition + Vector3.up * capsuleRadius; var point2 = playerPosition + Vector3.up * (capsuleCollider.height - capsuleRadius); var maxSize = Physics.CapsuleCastNonAlloc(point1, point2, capsuleRadius, direction, hits, 0f, SkillInputData.TargetLayer, QueryTriggerInteraction.Ignore); for (var i = 0; i < maxSize; i++) { if (!isAttacked) { var iDamageable = hits[i].transform.GetComponent(); iDamageable?.TakeDamage(Damage); isAttacked = true; } } yield return null; } SkillInputData.PlayerRb.velocity = Vector3.zero; SkillInputData.PlayerAgent.enabled = true; SkillInputData.PlayerRb.isKinematic = true; actions[0].Invoke(); isUsingSkill = false; SkillInputData.PlayerAnimator.SetBool("isLineRush", false); } } }