CapersProject/Assets/02.Scripts/Skill/Enemy/Boss/SandMole/SpikeBarrage.cs

137 lines
5.7 KiB
C#
Raw Normal View History

using System;
using System.Collections;
using BlueWater.Interfaces;
using BlueWater.Maps;
using BlueWater.Utility;
using UnityEngine;
namespace BlueWater.Enemies.Bosses.SandMole.Skills
{
public class SpikeBarrage : BaseSkill
{
private SpikeBarrageData _spikeBarrageData;
private AnimationController _animationController;
private AiMovement _aiMovement;
private Rigidbody _userRigidbody;
private Collider _userCollider;
private Collider _targetCollider;
private SpriteRenderer _userSpriteRenderer;
private SandMoleMapController _sandMoleMapController;
private Transform _particleInstantiateLocation;
private Transform _centerSpawnTransform;
private static readonly int _dissolveValueHash = Shader.PropertyToID("_DissolveValue");
protected override void BasicSetting()
{
_animationController = SkillUser.GetComponent<AnimationController>();
_aiMovement = SkillUser.GetComponent<AiMovement>();
_userRigidbody = SkillUser.GetComponent<Rigidbody>();
_userCollider = SkillUser.GetComponent<CapsuleCollider>();
_targetCollider = SkillUser.GetComponent<ITarget>().Target;
_userSpriteRenderer = SkillUser.GetComponentInChildren<SpriteRenderer>();
_sandMoleMapController = MapManager.Instance.SandMoleMapController;
_particleInstantiateLocation = _sandMoleMapController.ParticleInstanceLocation;
_centerSpawnTransform = _sandMoleMapController.CenterSpawnTransform;
_spikeBarrageData = (SpikeBarrageData)SkillData;
base.BasicSetting();
}
public override void ActivateSkill(params Action[] actions)
{
Utils.StartUniqueCoroutine(this, ref SkillCoroutineInstance, SkillCoroutine(actions));
}
private IEnumerator SkillCoroutine(params Action[] actions)
{
EnableSkill = false;
_aiMovement.StopMove();
_animationController.SetAnimationParameter("skillIndex", (int)SandMoleSkill.SpikeBarrage);
var animationStarted = false;
yield return StartCoroutine(_animationController.WaitForAnimationToRun("SpikeBarrage",
success => animationStarted = success));
if (!animationStarted || !SkillUser)
{
EndSkill(0, actions[0]);
yield break;
}
_userRigidbody.isKinematic = true;
_userSpriteRenderer.material.SetFloat(_dissolveValueHash, 1f);
var elapsedTime = 0f;
var dissolveTime = _spikeBarrageData.DissolveTime;
while (elapsedTime <= dissolveTime)
{
if (!_userSpriteRenderer)
{
EndSkill(0, actions[0]);
yield break;
}
var value = Mathf.Lerp(1f, 0f, elapsedTime / dissolveTime);
_userSpriteRenderer.material.SetFloat(_dissolveValueHash, value);
elapsedTime += Time.deltaTime;
yield return null;
}
_userSpriteRenderer.material.SetFloat(_dissolveValueHash, 0f);
_aiMovement.Teleport(SkillUser.transform.position + Vector3.up * 20f);
yield return new WaitForSeconds(1f);
_aiMovement.Teleport(_centerSpawnTransform.position);
_userRigidbody.isKinematic = false;
elapsedTime = 0f;
dissolveTime = _spikeBarrageData.SpawnDissolveTime;
while (elapsedTime <= dissolveTime)
{
if (!_userSpriteRenderer)
{
EndSkill(0, actions[0]);
yield break;
}
var value = Mathf.Lerp(0f, 1f, elapsedTime / dissolveTime);
_userSpriteRenderer.material.SetFloat(_dissolveValueHash, value);
elapsedTime += Time.deltaTime;
yield return null;
}
_userSpriteRenderer.material.SetFloat(_dissolveValueHash, 1f);
var startAngle = _spikeBarrageData.StartAngle;
var angleStep = _spikeBarrageData.AngleStep;
var spikeSpawnPosition = _userCollider.bounds.center;
spikeSpawnPosition.y = _targetCollider.bounds.center.y;
var spikeInterval = new WaitForSeconds(_spikeBarrageData.SpikeInterval);
for (var i = 0; i < _spikeBarrageData.SpikeCount; i++)
{
var currentAngle = startAngle + angleStep * i;
var rotation = Quaternion.Euler(0f, currentAngle, 0f);
var spike = Instantiate(_spikeBarrageData.SpikePrefab, spikeSpawnPosition, rotation,
_particleInstantiateLocation).GetComponent<ProjectileController>();
spike.Initialize(_spikeBarrageData.Damage, _spikeBarrageData.TargetLayer);
spike.AddForce(spike.transform.forward * _spikeBarrageData.ProjectileSpeed, ForceMode.Impulse);
yield return spikeInterval;
}
EndSkill(SkillData.Cooldown, actions[0]);
}
private void EndSkill(float cooldown, Action action)
{
Utils.EndUniqueCoroutine(this, ref SkillCoroutineInstance);
_animationController.ResetAnimationSpeed();
_animationController.SetAnimationParameter("skillIndex", (int)SandMoleSkill.None);
action?.Invoke();
Utils.StartUniqueCoroutine(this, ref CooldownCoroutineInstance,Utils.CoolDownCoroutine(cooldown, EndCooldown));
}
}
}