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; } _projectileObject.transform.position = _destination; _indicator.material.SetFloat(_fillHash, 1f); HideIndicator(); _projectileObject.DoAttack(); 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; } } }