+ Props 레이어, DamageableProps 레이어 구분 + 변경된 레이어에 따라서 TargetLayer들 변경 + ProjectileController, GateOfSpike 로직 수정 + Daily Bgm2로 변경
110 lines
4.6 KiB
C#
110 lines
4.6 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using BlueWater.Audios;
|
|
using BlueWater.Interfaces;
|
|
using BlueWater.Maps;
|
|
using BlueWater.Players;
|
|
using BlueWater.Utility;
|
|
using UnityEngine;
|
|
using Random = UnityEngine.Random;
|
|
|
|
namespace BlueWater.Enemies.Bosses.SandMole.Skills
|
|
{
|
|
public class GateOfSpikes : BaseSkill
|
|
{
|
|
private GateOfSpikesData _gateOfSpikesData;
|
|
private SpineController _spineController;
|
|
private Collider _userCollider;
|
|
private Collider _targetCollider;
|
|
private ICurrentDirection _currentDirection;
|
|
private Transform _particleInstantiateLocation;
|
|
|
|
private List<Vector3> _spikes;
|
|
|
|
protected override void BasicSetting()
|
|
{
|
|
_gateOfSpikesData = (GateOfSpikesData)SkillData;
|
|
_spineController = SkillUser.GetComponent<SpineController>();
|
|
_userCollider = SkillUser.GetComponent<CapsuleCollider>();
|
|
_targetCollider = SkillUser.GetComponent<ITarget>().Target;
|
|
_currentDirection = SkillUser.GetComponent<ICurrentDirection>();
|
|
_particleInstantiateLocation = MapManager.Instance.SandMoleMapController.ParticleInstanceLocation;
|
|
_spikes = new List<Vector3>(_gateOfSpikesData.SpikeCount);
|
|
|
|
base.BasicSetting();
|
|
}
|
|
|
|
public override void ActivateSkill(params Action[] actions)
|
|
{
|
|
Utils.StartUniqueCoroutine(this, ref SkillCoroutineInstance, SkillCoroutine(actions));
|
|
}
|
|
|
|
private IEnumerator SkillCoroutine(params Action[] actions)
|
|
{
|
|
EnableSkill = false;
|
|
_spineController.SetSkin(SandMoleSkin.Normal.ToString());
|
|
var roarTrack = _spineController.PlayAnimation(SandMoleAnimation.Roar.ToString(), false);
|
|
if (roarTrack == null)
|
|
{
|
|
EndSkill(0, actions[0]);
|
|
yield break;
|
|
}
|
|
|
|
yield return new WaitUntil(() => roarTrack.IsComplete);
|
|
|
|
AudioManager.Instance.PlaySfx("ThrowSpike");
|
|
AudioManager.Instance.PlaySfx("ThrowSpike");
|
|
AudioManager.Instance.PlaySfx("ThrowSpike");
|
|
|
|
_spineController.SetSkin(SandMoleSkin.Normal.ToString());
|
|
_spineController.PlayAnimation(SandMoleAnimation.Idle.ToString(), true);
|
|
|
|
IsUsingSkill = true;
|
|
var startPosition = SkillUser.transform.position;
|
|
var targetCenterPosition = _targetCollider.transform.position;
|
|
startPosition.y = targetCenterPosition.y;
|
|
var targetVector = targetCenterPosition - startPosition;
|
|
var targetDirection = targetVector.normalized;
|
|
_currentDirection.CurrentDirection = targetDirection;
|
|
var spikeSpawnPosition = _userCollider.bounds.center;
|
|
var validAttackPositions = new List<Vector3>();
|
|
|
|
while (validAttackPositions.Count < _gateOfSpikesData.SpikeCount)
|
|
{
|
|
var randomCircle = Random.insideUnitCircle * _gateOfSpikesData.Radius;
|
|
var randomPosition = targetCenterPosition + new Vector3(randomCircle.x, 0, randomCircle.y);
|
|
|
|
if (!IsPositionValid(randomPosition)) continue;
|
|
|
|
validAttackPositions.Add(randomPosition);
|
|
_spikes.Add(randomPosition);
|
|
var spike = Instantiate(_gateOfSpikesData.SpikePrefab, spikeSpawnPosition, Quaternion.identity,
|
|
_particleInstantiateLocation).GetComponent<GateOfSpike>();
|
|
spike.GetComponentInChildren<ProjectileController>().Initialize(_gateOfSpikesData.Damage, _gateOfSpikesData.TargetLayer, false);
|
|
spike.Initialize(randomPosition);
|
|
}
|
|
|
|
EndSkill(SkillData.Cooldown, actions[0]);
|
|
}
|
|
|
|
private bool IsPositionValid(Vector3 position)
|
|
{
|
|
var isGrounded = Physics.Raycast(position + Vector3.up, Vector3.down, 5f, _gateOfSpikesData.GroundLayer);
|
|
|
|
return isGrounded && _spikes.All(element => !(Vector3.Distance(position, element) < _gateOfSpikesData.MinDistanceBetweenAttacks));
|
|
}
|
|
|
|
private void EndSkill(float cooldown, Action action)
|
|
{
|
|
Utils.EndUniqueCoroutine(this, ref SkillCoroutineInstance);
|
|
|
|
_spineController.SetSkin(SandMoleSkin.Normal.ToString());
|
|
_spineController.PlayAnimation(SandMoleAnimation.Idle.ToString(), true);
|
|
action?.Invoke();
|
|
|
|
Utils.StartUniqueCoroutine(this, ref CooldownCoroutineInstance,Utils.CoolDownCoroutine(cooldown, EndCooldown));
|
|
}
|
|
}
|
|
} |