Files
SAMKWANG/Assets/Scripts/Branch/ObjectTourController.cs
2025-11-13 18:11:49 +09:00

89 lines
3.4 KiB
C#

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace Samkwang
{
public class ObjectTourController : MonoBehaviour
{
public Transform controlObject;
public ObjectTourPoint[] tourPoints;
public float moveSpeed = 2f; // 이동 속도 (SmoothDamp의 maxSpeed 대신 이동속도로 사용)
public float turnSpeedDegrees = 120f; // 초당 최대 회전 각도 (degree/sec)
public float arrivalThreshold = 0.05f;
// look-ahead: 목표에 가까워질때 다음 포인트 방향으로 미리 보도록 하는 거리
public float lookAheadDistance = 1.0f;
private int currentIndex = 0;
private void Start()
{
controlObject = transform.Find("Walking_cart").transform;
tourPoints = transform.GetComponentsInChildren<ObjectTourPoint>().OrderBy(p => p.transform.GetSiblingIndex()).ToArray();
if (tourPoints.Length > 0)
StartCoroutine(MoveTour());
}
private IEnumerator MoveTour()
{
while (true)
{
yield return StartCoroutine(MoveToTarget(currentIndex));
currentIndex = (currentIndex + 1) % tourPoints.Length;
}
}
private IEnumerator MoveToTarget(int index)
{
Transform target = tourPoints[index].transform;
Transform nextTarget = tourPoints[(index + 1) % tourPoints.Length].transform;
while (Vector3.Distance(controlObject.position, target.position) > arrivalThreshold)
{
// --- 위치 이동 (SmoothDamp style)
// SmoothDamp의 maxSpeed 파라미터 대신 단순 MoveTowards 기반으로 안정적 제어
float step = moveSpeed * Time.deltaTime;
controlObject.position = Vector3.MoveTowards(controlObject.position, target.position, step);
// --- 회전: look-ahead 처리
float distToTarget = Vector3.Distance(controlObject.position, target.position);
// 가까워질수록 다음 포인트를 더 바라보게 보간
Vector3 desiredLookPos;
if (distToTarget <= lookAheadDistance)
{
// 보간 비율: 0(멀때) -> 1(가까울때)
float t = Mathf.InverseLerp(lookAheadDistance, 0f, distToTarget);
Vector3 dirToCurrent = (target.position - controlObject.position).normalized;
Vector3 dirToNext = (nextTarget.position - controlObject.position).normalized;
Vector3 blendedDir = Vector3.Slerp(dirToCurrent, dirToNext, t).normalized;
desiredLookPos = controlObject.position + blendedDir;
}
else
{
desiredLookPos = target.position;
}
Vector3 dir = (desiredLookPos - controlObject.position);
if (dir.sqrMagnitude > 0.0001f)
{
Quaternion targetRot = Quaternion.LookRotation(dir.normalized);
// 초당 회전 한계를 적용 (더 자연스러운 회전)
float maxDeg = turnSpeedDegrees * Time.deltaTime;
controlObject.rotation = Quaternion.RotateTowards(controlObject.rotation, targetRot, maxDeg);
}
yield return null;
}
// 도착 후 정확히 위치/회전 정렬 (선택)
controlObject.position = target.position;
}
}
}