CapersProject/Assets/02.Scripts/Skill/Enemy/Boss/SandMole/GateOfSpikes.cs
Nam Tae Gun 7fb0da5888 #25, #26 아이템 직접 획득 방식 추가 및 선형적인 맵 구조 변경
+ Item관련 Excel, Json, So 수정
+ DropItemTable 로직 수정
+ 아이템 프리팹에서 Enable Interaction 체크하면 직접 룻팅, 해제하면 자동 룻팅
+ 체력회복 아이템 추가
+ 개발자 메뉴 상호작용 "F1" 키를 통해 접근 가능
+ 보스 맵은 마법진을 상호작용하면 보스전 시작
+ 맵 안에서 교전 중일 때, 투명 벽 쉐이더 추가
+ 맵 마다의 통로를 통해서 이동 가능
+ 선형적인 맵 구조에 맞게 리소스 및 위치 수정
+ 타이틀 화면으로 이동할 때 나타나는 오류 수정(CombatUiManager OnDisable 싱글톤 문제)

Closes #25, #26
2024-06-22 07:11:53 +09:00

106 lines
4.3 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using BlueWater.Maps;
using BlueWater.Utility;
using UnityEngine;
using Random = UnityEngine.Random;
namespace BlueWater.Enemies.Bosses.SandMole.Skills
{
public class GateOfSpikes : BaseSkill
{
private GateOfSpikesData _gateOfSpikesData;
private SandMole _sandMole;
private AnimationController _animationController;
private Collider _userCollider;
private Collider _targetCollider;
private Transform _particleInstantiateLocation;
private List<Vector3> _spikes;
protected override void BasicSetting()
{
if (!_sandMole)
{
_sandMole = SkillUser.GetComponent<SandMole>();
_animationController = _sandMole.AnimationController;
_userCollider = _sandMole.CharacterCollider;
_targetCollider = _sandMole.Target;
_particleInstantiateLocation = MapManager.Instance.SandMoleMapController.ParticleInstanceLocation;
}
_gateOfSpikesData = (GateOfSpikesData)SkillData;
_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;
_sandMole.StopMove();
_animationController.SetAnimationParameter("skillIndex", (int)SandMoleSkill.GateOfSpikes);
var animationStarted = false;
yield return StartCoroutine(_animationController.WaitForAnimationToRun("GateOfSpikes",
success => animationStarted = success));
if (!animationStarted || !SkillUser || !_userCollider)
{
EndSkill(0, actions[0]);
yield break;
}
IsUsingSkill = true;
_animationController.ResetAnimationSpeed();
var startPosition = SkillUser.transform.position;
var targetCenterPosition = _targetCollider.transform.position;
startPosition.y = targetCenterPosition.y;
var targetVector = targetCenterPosition - startPosition;
var targetDirection = targetVector.normalized;
_sandMole.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);
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);
_animationController.SetAnimationParameter("skillIndex", (int)SandMoleSkill.None);
action?.Invoke();
Utils.StartUniqueCoroutine(this, ref CooldownCoroutineInstance,Utils.CoolDownCoroutine(cooldown, EndCooldown));
}
}
}