using UnityEngine; using System.Collections; using System.Collections.Generic; public class TunnelTraveler : MonoBehaviour { public float travelSpeed = 25f; private bool _isTraveling = false; // 외부에서 읽기 전용으로 접근할 수 있게 합니다. public bool IsTraveling => _isTraveling; private CharacterController _controller; private Rigidbody _rigidbody; void Awake() { _controller = GetComponent(); _rigidbody = GetComponent(); } private IEnumerator TravelRoutine(List path, TunnelNode startNode) { _isTraveling = true; if (_controller != null) _controller.enabled = false; if (_rigidbody != null) _rigidbody.isKinematic = true; // 1. 캐릭터 높이 보정값 계산 float heightOffset = 0f; if (_controller != null) heightOffset = _controller.height / 2f; // 2. [입구 정렬] 시작 노드의 정확한 중앙 위치로 플레이어를 즉시 이동시킵니다. // 플레이어의 '발바닥' 위치를 노드 중앙보다 heightOffset만큼 아래로 맞춤 Vector3 entryPosition = new Vector3(startNode.transform.position.x, startNode.transform.position.y - heightOffset, startNode.transform.position.z); // 시작 지점으로 순간이동 또는 아주 빠르게 정렬 transform.position = entryPosition; // 3. 경로 이동 시작 foreach (Vector3 targetPos in path) { Vector3 adjustedTarget = new Vector3(targetPos.x, targetPos.y - heightOffset, targetPos.z); while (Vector3.Distance(transform.position, adjustedTarget) > 0.01f) { transform.position = Vector3.MoveTowards(transform.position, adjustedTarget, travelSpeed * Time.deltaTime); yield return null; } transform.position = adjustedTarget; } if (_rigidbody != null) _rigidbody.isKinematic = false; if (_controller != null) _controller.enabled = true; _isTraveling = false; } // StartTravel 함수에서 startNode를 코루틴에 넘겨주도록 수정 public void StartTravel(TunnelNode startNode) { if (_isTraveling) return; List path = GeneratePath(startNode); if (path.Count > 0) { // startNode 정보를 함께 넘김 StartCoroutine(TravelRoutine(path, startNode)); } } // GeneratePath 함수는 기존과 동일하게 유지합니다. private List GeneratePath(TunnelNode startNode) { List path = new List(); TunnelNode currentNode = startNode; HashSet visited = new HashSet(); while (currentNode != null && !visited.Contains(currentNode)) { visited.Add(currentNode); TunnelNode exitNode = currentNode.otherEndOfThisSegment; if (exitNode == null) break; path.Add(exitNode.transform.position); currentNode = exitNode.connectedNode; } return path; } }