using System.Collections; using UnityEngine; public class FallingStalactite : MonoBehaviour { [Header("References")] [SerializeField] private Rigidbody rb; [SerializeField] private Collider damageCollider; [SerializeField] private DamageObstacle damageObstacle; [Header("Fall Settings")] [SerializeField] private float fallDelay = 0.0f; [Tooltip("떨어질 때 아래 방향으로 추가 속도를 줍니다.")] [SerializeField] private float initialDownVelocity = 0f; [Tooltip("떨어질 때 약간 회전시키고 싶으면 값을 넣습니다.")] [SerializeField] private Vector3 initialAngularVelocity = new Vector3(0f, 0f, 0f); [Header("Damage")] [SerializeField] private int damage = 10; [Tooltip("떨어지기 전에는 데미지를 끄고, 떨어질 때 켭니다.")] [SerializeField] private bool damageOnlyWhileFalling = true; [Header("Reset Option")] [SerializeField] private bool resetAfterFall = true; [Tooltip("떨어진 뒤 몇 초 후 원래 위치로 돌아갈지 설정합니다.")] [SerializeField] private float resetDelay = 4.0f; [Tooltip("리셋할 때 종유석을 다시 숨기지 않고 원위치에 고정합니다.")] [SerializeField] private bool readyAgainAfterReset = true; [Header("Debug")] [SerializeField] private bool showDebugLog = true; private Vector3 startPosition; private Quaternion startRotation; private bool hasFallen; private Coroutine fallRoutine; public bool HasFallen => hasFallen; private void Awake() { ResolveReferences(); startPosition = transform.position; startRotation = transform.rotation; PrepareStalactite(); } private void ResolveReferences() { if (rb == null) rb = GetComponent(); if (damageCollider == null) damageCollider = GetComponent(); if (damageObstacle == null) damageObstacle = GetComponent(); } private void PrepareStalactite() { if (rb != null) { rb.useGravity = false; rb.isKinematic = true; rb.linearVelocity = Vector3.zero; rb.angularVelocity = Vector3.zero; } if (damageObstacle != null) { damageObstacle.SetDamage(damage); damageObstacle.SetCanDamage(!damageOnlyWhileFalling); } if (damageCollider != null) { damageCollider.enabled = true; } hasFallen = false; } public void TriggerFall() { if (hasFallen) return; if (fallRoutine != null) StopCoroutine(fallRoutine); fallRoutine = StartCoroutine(FallRoutine()); } private IEnumerator FallRoutine() { hasFallen = true; if (fallDelay > 0f) yield return new WaitForSeconds(fallDelay); if (damageObstacle != null) { damageObstacle.SetDamage(damage); damageObstacle.SetCanDamage(true); } if (rb != null) { rb.isKinematic = false; rb.useGravity = true; if (initialDownVelocity > 0f) { rb.linearVelocity = Vector3.down * initialDownVelocity; } rb.angularVelocity = initialAngularVelocity; } if (showDebugLog) Debug.Log($"[FallingStalactite] {name} 낙하 시작. 데미지 {damage}", this); if (resetAfterFall) { yield return new WaitForSeconds(resetDelay); ResetStalactite(); } fallRoutine = null; } public void ResetStalactite() { if (rb != null) { rb.linearVelocity = Vector3.zero; rb.angularVelocity = Vector3.zero; rb.useGravity = false; rb.isKinematic = true; } transform.position = startPosition; transform.rotation = startRotation; if (damageObstacle != null) { damageObstacle.SetDamage(damage); damageObstacle.SetCanDamage(!damageOnlyWhileFalling); } if (readyAgainAfterReset) { hasFallen = false; } if (showDebugLog) Debug.Log($"[FallingStalactite] {name} 원위치 리셋", this); } }