+ Item관련 Excel, Json, So 수정 + DropItemTable 로직 수정 + 아이템 프리팹에서 Enable Interaction 체크하면 직접 룻팅, 해제하면 자동 룻팅 + 체력회복 아이템 추가 + 개발자 메뉴 상호작용 "F1" 키를 통해 접근 가능 + 보스 맵은 마법진을 상호작용하면 보스전 시작 + 맵 안에서 교전 중일 때, 투명 벽 쉐이더 추가 + 맵 마다의 통로를 통해서 이동 가능 + 선형적인 맵 구조에 맞게 리소스 및 위치 수정 + 타이틀 화면으로 이동할 때 나타나는 오류 수정(CombatUiManager OnDisable 싱글톤 문제) Closes #25, #26
137 lines
5.7 KiB
C#
137 lines
5.7 KiB
C#
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));
|
|
}
|
|
}
|
|
} |