using UnityEngine; [DisallowMultipleComponent] public class MovingMazeWall : MonoBehaviour { [Header("Movement")] [Tooltip("로컬 좌표 기준 이동 거리입니다.")] [SerializeField] private Vector3 localMoveOffset = new Vector3(0f, 0f, 2f); [SerializeField] private float speed = 1f; [Header("Timing")] [Tooltip("움직이기 전 대기 시간입니다.")] [SerializeField] private float startDelay = 0f; [Tooltip("여러 벽이 같은 타이밍으로 움직이지 않게 하는 시간 오프셋입니다.")] [SerializeField] private float phaseOffset = 0f; [Header("Options")] [SerializeField] private bool moveOnStart = true; [SerializeField] private bool useUnscaledTime = false; private Vector3 startLocalPosition; private bool isMoving; private float moveStartTime; private void Awake() { startLocalPosition = transform.localPosition; isMoving = moveOnStart; moveStartTime = GetCurrentTime(); } private void Update() { if (!isMoving) return; float time = GetCurrentTime() - moveStartTime + phaseOffset - startDelay; if (time < 0f) return; float t = Mathf.PingPong(time * speed, 1f); transform.localPosition = Vector3.Lerp( startLocalPosition, startLocalPosition + localMoveOffset, t ); } private float GetCurrentTime() { return useUnscaledTime ? Time.unscaledTime : Time.time; } public void StartMove() { isMoving = true; moveStartTime = GetCurrentTime(); } public void StopMove() { isMoving = false; } public void ResetWallPosition() { transform.localPosition = startLocalPosition; moveStartTime = GetCurrentTime(); } public void ResetWallPosition(bool keepMoving) { transform.localPosition = startLocalPosition; isMoving = keepMoving; moveStartTime = GetCurrentTime(); } public void ResetAndStop() { ResetWallPosition(false); } public void ResetAndStart() { ResetWallPosition(true); } public void ResetToInitialState() { ResetWallPosition(moveOnStart); } #if UNITY_EDITOR private void OnValidate() { speed = Mathf.Max(0f, speed); startDelay = Mathf.Max(0f, startDelay); } #endif }