OldBlueWater/BlueWater/Assets/02.Scripts/NewSkill/Rhinoceros/SeismicThrust.cs

114 lines
4.3 KiB
C#

using System;
using System.Collections;
using BlueWaterProject;
using Sirenix.OdinInspector;
using UnityEngine;
// ReSharper disable once CheckNamespace
namespace RhinocerosSkill
{
public class SeismicThrust : BaseSkill
{
[Title("추가 옵션")]
[SerializeField] private bool isDrawingGizmo = true;
[SerializeField] private float width = 3f;
[SerializeField] private GameObject earthquakeParticlePrefab;
private Transform particleInstantiateLocation;
private Vector3 startPosition;
private Vector3 halfScale;
private RaycastHit[] hits;
private bool isUsingSkill;
private void OnDrawGizmos()
{
if (!isDrawingGizmo || !isUsingSkill) return;
Gizmos.color = Color.red;
Gizmos.matrix = Matrix4x4.TRS(startPosition, transform.rotation, Vector3.one);
Gizmos.DrawWireCube(Vector3.zero, halfScale * 2f);
Gizmos.matrix = Matrix4x4.identity;
}
protected override void BasicSetting()
{
base.BasicSetting();
hits = new RaycastHit[5];
}
public override bool EnableSkill()
{
if (!enableSkill) return false;
var targetDistance = Vector3.Distance(SkillInputData.Transform.position,
SkillInputData.TargetCollider.transform.position);
return targetDistance <= SkillData.Range;
}
public override void ActivateSkill(params Action[] actions)
{
enableSkill = false;
StartCoroutine(SkillCoroutine(actions));
}
private IEnumerator SkillCoroutine(params Action[] actions)
{
isUsingSkill = true;
transform.position = SkillInputData.Transform.position;
var angle = Mathf.Atan2(SkillInputData.PreviousDirection.x, SkillInputData.PreviousDirection.z) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(0, angle, 0);
transform.localScale = new Vector3(width, 6f, SkillData.Range * 2);
var myLocalScale = transform.localScale;
halfScale = new Vector3(myLocalScale.x * 0.5f, myLocalScale.y * 0.5f, myLocalScale.z * 0.25f);
ShowIndicator();
var elapsedTime = 0f;
var fill = 1 / SkillData.CastingTime;
while (elapsedTime < SkillData.CastingTime)
{
elapsedTime += Time.deltaTime;
if (isUsingIndicator && indicator)
{
var fillValue = indicator.material.GetFloat(FillHash) + Time.deltaTime * fill;
indicator.material.SetFloat(FillHash, fillValue);
}
yield return null;
}
particleInstantiateLocation ??= FindAnyObjectByType<RhinocerosBossMapController>().ParticleInstantiateLocation;
Instantiate(earthquakeParticlePrefab, transform.position + transform.forward * 4f, transform.rotation, particleInstantiateLocation);
startPosition = transform.position + transform.forward * halfScale.z;
var maxSize = Physics.BoxCastNonAlloc(startPosition, halfScale, transform.forward,
hits, transform.rotation, 0f, SkillInputData.TargetLayer, QueryTriggerInteraction.Ignore);
for (var i = 0; i < maxSize; i++)
{
var iDamageable = hits[i].transform.GetComponent<IDamageable>();
iDamageable?.TakeDamage(SkillData.Damage);
var combatStatus = hits[i].transform.GetComponent<CombatStatus>();
if (combatStatus != null)
{
combatStatus.Stun(0.15f);
combatStatus.SlowMoveSpeed(5f, 0.5f);
combatStatus.GetComponent<Rigidbody>().AddForce(transform.forward * 20f, ForceMode.Impulse);
}
}
HideIndicator();
EndSkill(SkillData.Cooldown, actions[0]);
}
private void EndSkill(float cooldown, Action action)
{
StartCoroutine(Utils.CoolDown(cooldown, () => enableSkill = true));
action?.Invoke();
}
}
}