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().StopStun(); } } 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.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; 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); } var stunRange = Range * 2f; maxSize = Physics.OverlapSphereNonAlloc(transform.position, stunRange, hitColliders, SkillInputData.TargetLayer); for (var i = 0; i < maxSize; i++) { var iCombatable = hitColliders[i].GetComponent(); if (iCombatable != null) { var targetToVector = hitColliders[i].transform.position - transform.position; targetToVector.y = 0f; var direction = targetToVector.normalized; direction = direction == Vector3.zero ? Vector3.right : direction; var distance = targetToVector.magnitude; var powerCoefficient = stunRange - distance; var addForcePower = powerCoefficient / stunRange * 10f; iCombatable.Stun(stunTime); iCombatable.AddForceToDirection(direction, addForcePower); } } SkillInputData.PlayerAnimator.SetBool("isJump", false); SkillInputData.PlayerAnimator.SetTrigger("isSmash"); actions[0].Invoke(); } private void IgnoreCollision(bool value) { Physics.IgnoreCollision(SkillInputData.PlayerCollider, SkillInputData.TargetCollider, value); } } }