using System; using System.Collections; using BlueWaterProject; using Sirenix.OdinInspector; using UnityEngine; using UnityEngine.Rendering.Universal; // ReSharper disable once CheckNamespace namespace RhinocerosSkill { public class JumpSmash : SkillBase { [Title("추가 옵션")] [SerializeField] private float upTime = 0.1f; [SerializeField] private float waitTime = 1f; [SerializeField] private float downTime = 0.1f; [SerializeField] private float stunTime = 2f; [SerializeField] protected DecalProjector stunIndicator; private Collider[] hitColliders; private void OnDestroy() { if (SkillInputData.TargetCollider) { SkillInputData.TargetCollider.GetComponent().MyCurrentState.IsStunned = false; } } public override void ActivateSkill(params Action[] actions) { ReadySkill = false; SkillInputData.PlayerAnimator.SetBool("isJump", true); CoolDown(Cooldown, () => ReadySkill = true); StartCoroutine(SkillCoroutine(actions)); } public override bool EnableSkill() { if (!ReadySkill) return false; return true; } protected override void BasicSetting() { if (isUsingIndicator) { if (indicator) { indicator.scaleMode = DecalScaleMode.InheritFromHierarchy; indicator.material = new Material(indicator.material); indicator.material.SetFloat(FillHash, 0f); } if (stunIndicator) { stunIndicator.scaleMode = DecalScaleMode.InheritFromHierarchy; stunIndicator.material = new Material(stunIndicator.material); stunIndicator.material.SetFloat(FillHash, 0f); } } hitColliders = new Collider[5]; } protected override void HideIndicator() { if (isUsingIndicator) { if (indicator) { indicator.enabled = false; indicator.material.SetFloat(FillHash, 0); } if (stunIndicator) { stunIndicator.enabled = false; stunIndicator.material.SetFloat(FillHash, 0); } } } protected override void ShowIndicator() { if (isUsingIndicator) { if (indicator) { indicator.material.SetFloat(FillHash, 0); indicator.enabled = true; } if (stunIndicator) { stunIndicator.material.SetFloat(FillHash, 0); stunIndicator.enabled = true; } } } private IEnumerator SkillCoroutine(params Action[] actions) { while (!SkillInputData.PlayerAnimator.GetCurrentAnimatorStateInfo(0).IsName("Jump")) { yield return null; } while (SkillInputData.PlayerAnimator.GetCurrentAnimatorStateInfo(0).IsName("Jump") && SkillInputData.PlayerAnimator.GetCurrentAnimatorStateInfo(0).normalizedTime < 1.0f) { yield return null; } SkillInputData.PlayerAgent.enabled = false; SkillInputData.PlayerRb.useGravity = false; var elapsedTime = 0f; var startPosition = SkillInputData.PlayerRb.transform.position; var endPosition = startPosition + Vector3.up * 15f; while (elapsedTime < upTime) { elapsedTime += Time.deltaTime; SkillInputData.PlayerRb.position = Vector3.Lerp(startPosition, endPosition, elapsedTime / upTime); yield return null; } SkillInputData.PlayerRb.position = endPosition; yield return new WaitForSeconds(waitTime); var targetPosition = SkillInputData.TargetCollider.transform.position; transform.position = targetPosition; transform.localScale = Vector3.one * (Range * 2f); stunIndicator.transform.localScale = Vector3.one * 4f; startPosition = targetPosition + Vector3.up * 15f; endPosition = targetPosition; ShowIndicator(); elapsedTime = 0f; var fill = 1 / CastingTime; while (elapsedTime < CastingTime) { elapsedTime += Time.deltaTime; if (isUsingIndicator) { var fillValue = indicator.material.GetFloat(FillHash) + Time.deltaTime * fill; if (indicator) { indicator.material.SetFloat(FillHash, fillValue); } if (stunIndicator) { stunIndicator.material.SetFloat(FillHash, fillValue); } } yield return null; } IgnoreCollision(true); elapsedTime = 0f; while (elapsedTime < downTime) { elapsedTime += Time.deltaTime; SkillInputData.PlayerRb.position = Vector3.Lerp(startPosition, endPosition, elapsedTime / downTime); yield return null; } VisualFeedbackManager.Inst.CameraShake(CameraManager.Inst.CombatCamera.BaseCombatCamera, 3f, 1f); SkillInputData.PlayerRb.useGravity = true; SkillInputData.PlayerAgent.enabled = true; SkillInputData.PlayerRb.position = endPosition; var targetToVector = SkillInputData.TargetCollider.transform.position - SkillInputData.PlayerCollider.transform.position; targetToVector.y = 0f; var playerRadius = ((CapsuleCollider)SkillInputData.PlayerCollider).radius; if (targetToVector.magnitude < playerRadius) { var direction = targetToVector.normalized; direction = direction == Vector3.zero ? Vector3.right : direction; SkillInputData.TargetCollider.transform.GetComponent().AddForce(direction * 70f, ForceMode.Impulse); CoolDown(1f, () => IgnoreCollision(false)); } else { IgnoreCollision(false); } HideIndicator(); var maxSize = Physics.OverlapSphereNonAlloc(transform.position, Range, hitColliders, SkillInputData.TargetLayer); for (var i = 0; i < maxSize; i++) { var iDamageable = hitColliders[i].GetComponent(); iDamageable?.TakeDamage(Damage); } maxSize = Physics.OverlapSphereNonAlloc(transform.position, Range * 2f, hitColliders, SkillInputData.TargetLayer); for (var i = 0; i < maxSize; i++) { var physicsMovement = hitColliders[i].GetComponent(); if (physicsMovement != null && !physicsMovement.MyCurrentState.isDashing) { StartCoroutine(StunCoroutine(physicsMovement)); } } SkillInputData.PlayerAnimator.SetBool("isJump", false); SkillInputData.PlayerAnimator.SetTrigger("isSmash"); actions[0].Invoke(); } private IEnumerator StunCoroutine(PhysicsMovement physicsMovement) { physicsMovement.MyCurrentState.isMoving = false; physicsMovement.MyCurrentState.IsStunned = true; var elapsedTime = 0f; while (elapsedTime < stunTime) { elapsedTime += Time.deltaTime; yield return null; } physicsMovement.MyCurrentState.IsStunned = false; } private void IgnoreCollision(bool value) { Physics.IgnoreCollision(SkillInputData.PlayerCollider, SkillInputData.TargetCollider, value); } } }