CapersProject/Assets/02.Scripts/Skill/Enemy/Boss/Rhinoceros/BullCharge.cs

161 lines
6.5 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 BullCharge : BaseSkill
{
[Title("추가 옵션")]
[SerializeField]
private bool _isDrawingGizmo = true;
private BullChargeData _bullChargeData;
private Rhinoceros _rhinoceros;
private AnimationController _animationController;
private Rigidbody _userRigidbody;
private CapsuleCollider _userCollider;
private Collider _targetCollider;
private float _colliderRadius;
private float _attackRadius;
private void OnDrawGizmos()
{
if (!_isDrawingGizmo || !IsUsingSkill) return;
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(SkillUser.transform.position, _attackRadius);
}
protected override void BasicSetting()
{
if (!_rhinoceros)
{
_rhinoceros = SkillUser.GetComponent<Rhinoceros>();
_animationController = _rhinoceros.AnimationController;
_userRigidbody = _rhinoceros.Rigidbody;
_userCollider = _rhinoceros.CharacterCollider;
_targetCollider = _rhinoceros.Target;
_colliderRadius = _userCollider.radius * _rhinoceros.transform.localScale.x;
_attackRadius = _colliderRadius * 0.5f;
}
_bullChargeData = (BullChargeData)SkillData;
RaycastHits = new RaycastHit[5];
base.BasicSetting();
}
public override void ActivateSkill(params Action[] actions)
{
Utils.StartUniqueCoroutine(this, ref SkillCoroutineInstance, SkillCoroutine(actions));
}
private IEnumerator SkillCoroutine(params Action[] actions)
{
EnableSkill = false;
_rhinoceros.StopMove();
_animationController.SetAnimationParameter("skillIndex", (int)RhinocerosSkill.BullCharge);
var animationStarted = false;
yield return StartCoroutine(_animationController.WaitForAnimationToRun("BullCharge",
success => animationStarted = success));
if (!animationStarted)
{
EndSkill(0, actions[0]);
yield break;
}
_animationController.ResetAnimationSpeed();
IsUsingSkill = true;
var isAttacked = false;
var startPosition = SkillUser.transform.position;
var targetVector = _targetCollider.transform.position - startPosition;
targetVector.y = 0f;
var targetDirection = targetVector.normalized;
var targetDistance = targetVector.magnitude + _bullChargeData.ChargeOffset;
transform.position = startPosition + Vector3.up * 3f;
transform.localScale = new Vector3(_colliderRadius, 6f, targetDistance * 2);
var angle = Mathf.Atan2(targetDirection.x, targetDirection.z) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(0, angle, 0);
_rhinoceros.CurrentDirection = targetDirection;
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;
}
HideIndicator();
var totalDistanceCovered = 0f;
while (totalDistanceCovered < targetDistance)
{
var moveDistance = _bullChargeData.ChargeSpeed * Time.fixedDeltaTime;
var skillUserPosition = SkillUser.transform.position;
var hitCount = Physics.SphereCastNonAlloc(skillUserPosition, _attackRadius, targetDirection,
RaycastHits, 0f, _bullChargeData.TargetLayer, QueryTriggerInteraction.Collide);
_userRigidbody.MovePosition(skillUserPosition + targetDirection * moveDistance);
for (var i = 0; i < hitCount; i++)
{
if (isAttacked) continue;
var raycastHit = RaycastHits[i];
var iDamageable = raycastHit.transform.GetComponentInParent<IDamageable>();
if (iDamageable == null || !iDamageable.CanDamage()) continue;
iDamageable.TakeDamage(SkillData.Damage);
isAttacked = true;
var iStunnable = raycastHit.transform.GetComponentInParent<IStunnable>();
iStunnable?.TryStun(_bullChargeData.StunDuration);
var iPhysicMovable = raycastHit.transform.GetComponentInParent<IPhysicMovable>();
if (iPhysicMovable == null) continue;
var hitVector = raycastHit.transform.position - SkillUser.transform.position;
hitVector.y = 0f;
var hitDirection = hitVector.normalized;
iPhysicMovable.SetPush(hitDirection, _bullChargeData.PushPower);
// var cross = Vector3.Cross(hitDirection, transform.forward);
// var addForceDirection = cross.y >= 0f ? Quaternion.Euler(0, -90, 0) * transform.forward : Quaternion.Euler(0, 90, 0) * transform.forward;
// iPhysicMovable.AddForce(addForceDirection * _bullChargeData.PushPower, ForceMode.Impulse);
}
totalDistanceCovered += moveDistance;
yield return new WaitForFixedUpdate();
}
EndSkill(SkillData.Cooldown, actions[0]);
}
private void EndSkill(float cooldown, Action action)
{
Utils.EndUniqueCoroutine(this, ref SkillCoroutineInstance);
_animationController.SetAnimationParameter("skillIndex", (int)RhinocerosSkill.None);
action?.Invoke();
IsUsingSkill = false;
Utils.StartUniqueCoroutine(this, ref CooldownCoroutineInstance,Utils.CoolDownCoroutine(cooldown, EndCooldown));
}
}
}