CapersProject/Assets/02.Scripts/Prop/GateOfSpike.cs
Nam Tae Gun d27ac0918b #17 모래두더지 가시 일제 사격 스킬(GateOfSpike) 추가
+ 고정된 싸이클의 BehaviorTree로 변경
+ ProjectileController로직을 SphereCast -> OverlapSphereNonAlloc으로 변경
+ GateOfSpikes 관련 파티클 추가
+ GateOfSpike 클래스는 단일 오브젝트 컨트롤러
2024-06-15 08:37:41 +09:00

123 lines
3.9 KiB
C#

using System.Collections;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.Rendering.Universal;
namespace BlueWater
{
public class GateOfSpike : MonoBehaviour
{
[Title("컴포넌트")]
[SerializeField, Required]
private ProjectileController _projectileObject;
[SerializeField, Required]
private Rigidbody _rigidbody;
[SerializeField, Required]
private SphereCollider _sphereCollider;
[SerializeField, Required]
private DecalProjector _indicator;
[Title("표시기 설정")]
[SerializeField]
private bool _isUsingIndicator = true;
[Title("설정")]
[SerializeField]
private float _maxHeight = 10f;
[SerializeField]
private Vector2 _randomDuration = new(1f, 1.5f);
private bool _isInitialized;
private Vector3 _destination;
// Hashes
private static readonly int _fillHash = Shader.PropertyToID("_Fill");
private IEnumerator Start()
{
yield return new WaitUntil(() => _isInitialized);
BasicSetting();
ShowIndicator();
var startPosition = transform.position;
var controlPoint = startPosition + Vector3.up * _maxHeight;
var elapsedTime = 0f;
var duration = Random.Range(_randomDuration.x, _randomDuration.y);
while (elapsedTime < duration)
{
if (!_projectileObject)
{
HideIndicator();
Destroy(gameObject, 3.5f);
yield break;
}
elapsedTime += Time.deltaTime;
var t = elapsedTime / duration;
if (_isUsingIndicator && _indicator)
{
var fillValue = Mathf.Lerp(0f, 1f, t);
if (t == 0f)
{
fillValue = 0f;
}
_indicator.material.SetFloat(_fillHash, fillValue);
}
// 베지어 곡선을 사용하여 위치 계산
var position = Mathf.Pow(1 - t, 2) * startPosition +
2 * (1 - t) * t * controlPoint +
Mathf.Pow(t, 2) * _destination;
_projectileObject.transform.position = position;
yield return null;
}
_indicator.material.SetFloat(_fillHash, 1f);
HideIndicator();
Destroy(gameObject, 3.5f);
}
public void Initialize(Vector3 destination)
{
_destination = destination;
_isInitialized = true;
}
private void BasicSetting()
{
if (!_isUsingIndicator || !_indicator) return;
_indicator.scaleMode = DecalScaleMode.InheritFromHierarchy;
_indicator.material = new Material(_indicator.material);
_indicator.material.SetFloat(_fillHash, 0f);
var indicatorScale = _projectileObject.SphereRadius * 2f;
_indicator.transform.localScale = Vector3.one * indicatorScale;
_indicator.transform.position = _destination + Vector3.up * _sphereCollider.radius;
}
private void HideIndicator()
{
if (!_isUsingIndicator || !_indicator) return;
_indicator.enabled = false;
_indicator.material.SetFloat(_fillHash, 0);
}
private void ShowIndicator()
{
if (!_isUsingIndicator || !_indicator) return;
_indicator.material.SetFloat(_fillHash, 0);
_indicator.enabled = true;
}
}
}