145 lines
5.1 KiB
C#
145 lines
5.1 KiB
C#
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>();
|
|
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);
|
|
}
|
|
}
|
|
} |