247 lines
8.5 KiB
C#
247 lines
8.5 KiB
C#
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<PhysicsMovement>().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<Rigidbody>().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>();
|
|
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<PhysicsMovement>();
|
|
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);
|
|
}
|
|
}
|
|
} |