130 lines
5.1 KiB
C#
130 lines
5.1 KiB
C#
using System;
|
|
using System.Collections;
|
|
using BlueWater.Interfaces;
|
|
using BlueWater.Utility;
|
|
using Sirenix.OdinInspector;
|
|
using UnityEngine;
|
|
|
|
namespace BlueWater.Enemies.Bosses.Rhinoceros.Skills
|
|
{
|
|
public class SeismicThrust : BaseSkill
|
|
{
|
|
[Title("추가 옵션")]
|
|
[SerializeField]
|
|
private bool _isDrawingGizmo = true;
|
|
|
|
private SeismicThrustData _seismicThrustData;
|
|
private Rhinoceros _rhinoceros;
|
|
private Collider _targetCollider;
|
|
private Transform _particleInstantiateLocation;
|
|
private GameObject _seismicThrustParticle;
|
|
|
|
private Vector3 _startPosition;
|
|
private Vector3 _halfScale;
|
|
|
|
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;
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
if (_seismicThrustParticle)
|
|
{
|
|
Destroy(gameObject);
|
|
}
|
|
}
|
|
|
|
protected override void BasicSetting()
|
|
{
|
|
if (!_rhinoceros)
|
|
{
|
|
_rhinoceros = SkillUser.GetComponent<Rhinoceros>();
|
|
_targetCollider = _rhinoceros.Target;
|
|
_particleInstantiateLocation = _rhinoceros.BossMapController.ParticleInstanceLocation;
|
|
}
|
|
_seismicThrustData = (SeismicThrustData)SkillData;
|
|
RaycastHits = new RaycastHit[4];
|
|
|
|
base.BasicSetting();
|
|
}
|
|
|
|
public override bool CanSkill()
|
|
{
|
|
if (!EnableSkill) return false;
|
|
|
|
var targetDistance = Vector3.Distance(SkillUser.transform.position,_targetCollider.transform.position);
|
|
return targetDistance <= SkillData.Radius;
|
|
}
|
|
|
|
public override void ActivateSkill(params Action[] actions)
|
|
{
|
|
Utils.StartUniqueCoroutine(this, ref SkillCoroutineInstance, SkillCoroutine(actions));
|
|
}
|
|
|
|
private IEnumerator SkillCoroutine(params Action[] actions)
|
|
{
|
|
EnableSkill = false;
|
|
IsUsingSkill = true;
|
|
transform.position = SkillUser.transform.position + Vector3.up * 3f;
|
|
var angle = Mathf.Atan2(_rhinoceros.CurrentDirection.x, _rhinoceros.CurrentDirection.z) * Mathf.Rad2Deg;
|
|
transform.rotation = Quaternion.Euler(0, angle, 0);
|
|
transform.localScale = new Vector3(_seismicThrustData.HorizontalRange, 6f, SkillData.Radius * 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;
|
|
}
|
|
|
|
_seismicThrustParticle = Instantiate(_seismicThrustData.SeismicThrustParticle,
|
|
SkillUser.transform.position + transform.forward * 4f, transform.rotation, _particleInstantiateLocation);
|
|
_startPosition = SkillUser.transform.position + transform.forward * _halfScale.z;
|
|
var maxSize = Physics.BoxCastNonAlloc(_startPosition, _halfScale, transform.forward,
|
|
RaycastHits, transform.rotation, 0f, _seismicThrustData.TargetLayer, QueryTriggerInteraction.Collide);
|
|
for (var i = 0; i < maxSize; i++)
|
|
{
|
|
var raycastHit = RaycastHits[i];
|
|
var iDamageable = raycastHit.transform.GetComponentInParent<IDamageable>();
|
|
if (iDamageable == null || !iDamageable.CanDamage()) continue;
|
|
|
|
iDamageable.TakeDamage(SkillData.Damage);
|
|
|
|
var iStunnable = raycastHit.transform.GetComponentInParent<IStunnable>();
|
|
iStunnable?.TryStun(_seismicThrustData.StunDuration);
|
|
|
|
var iSlowable = raycastHit.transform.GetComponentInParent<ISlowable>();
|
|
iSlowable?.TrySlowMoveSpeed(_seismicThrustData.SlowDuration, _seismicThrustData.SlowCoefficient);
|
|
}
|
|
|
|
HideIndicator();
|
|
EndSkill(SkillData.Cooldown, actions[0]);
|
|
}
|
|
|
|
private void EndSkill(float cooldown, Action action)
|
|
{
|
|
Utils.EndUniqueCoroutine(this, ref SkillCoroutineInstance);
|
|
|
|
action?.Invoke();
|
|
Utils.StartUniqueCoroutine(this, ref CooldownCoroutineInstance,Utils.CoolDownCoroutine(cooldown, EndCooldown));
|
|
}
|
|
}
|
|
} |