Files
ProjectMD/Assets/Scripts/TunnelTraveler.cs

90 lines
3.2 KiB
C#

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<CharacterController>();
_rigidbody = GetComponent<Rigidbody>();
}
private IEnumerator TravelRoutine(List<Vector3> 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<Vector3> path = GeneratePath(startNode);
if (path.Count > 0)
{
// startNode 정보를 함께 넘김
StartCoroutine(TravelRoutine(path, startNode));
}
}
// GeneratePath 함수는 기존과 동일하게 유지합니다.
private List<Vector3> GeneratePath(TunnelNode startNode)
{
List<Vector3> path = new List<Vector3>();
TunnelNode currentNode = startNode;
HashSet<TunnelNode> visited = new HashSet<TunnelNode>();
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;
}
}