Merge branch 'feature/entitynetworkterminal' of http://xr.flexing.ai:3000/UVCXR/OCTOPUS_TWIN-Demo

This commit is contained in:
wsh
2026-02-10 11:56:39 +09:00
15 changed files with 631 additions and 61 deletions

View File

@@ -0,0 +1,36 @@
using UnityEngine;
namespace OCTOPUS_TWIN
{
/// <summary>
/// 카메라 경유점. CameraRoute의 자식 오브젝트에 추가하여 궤도 파라미터를 설정.
/// 없으면 자식 Transform의 position만 사용하고 궤도 파라미터는 현재 카메라 상태 유지.
/// </summary>
public class CameraRoutePoint : MonoBehaviour
{
public float elevation = 45f;
public float azimuth = 0f;
public float distance = 30f;
[Tooltip("이 지점까지의 이동 시간(초)")]
public float duration = 0.5f;
[Tooltip("이 지점에서의 대기 시간(초)")]
public float waitTime = 0f;
}
/// <summary>
/// 카메라 이동 경로. 자식 Transform 순서대로 카메라가 보간 이동.
/// 각 자식에 CameraRoutePoint를 추가하면 궤도 파라미터(elevation, azimuth, distance)도 제어 가능.
/// </summary>
public class CameraRoute : MonoBehaviour
{
public bool loop;
public int PointCount => transform.childCount;
public (Vector3 position, CameraRoutePoint point) GetWaypoint(int index)
{
var child = transform.GetChild(index);
return (child.position, child.GetComponent<CameraRoutePoint>());
}
}
}

View File

@@ -62,6 +62,8 @@ namespace OCTOPUS_TWIN
private bool isZoomOperation;
public bool Enable;
public bool IsRouteActive => routeSequence != null && routeSequence.IsActive();
private Sequence routeSequence;
public bool IsClickUI
{
@@ -148,11 +150,11 @@ namespace OCTOPUS_TWIN
private void LateUpdate()
{
//UI 위에서 카메라 움직임 제한
//UI <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ī<>޶<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
if (IsClickUI || IsOnTheUI)
return;
//라이브러리에서 오브젝트 배치시 카메라 움직임 제한
//<EFBFBD><EFBFBD><EFBFBD>̺귯<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ <20><>ġ<EFBFBD><C4A1> ī<>޶<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
if (!Enable)
{
return;
@@ -298,7 +300,7 @@ namespace OCTOPUS_TWIN
{
camera.orthographic = false;
currentElevation = perspectiveState.elevation; //90 안 섞임
currentElevation = perspectiveState.elevation; //90 <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
currentDistance = perspectiveState.distance;
currentAzimuth = perspectiveState.azimuth;
@@ -339,7 +341,7 @@ namespace OCTOPUS_TWIN
break;
case ViewMode.TopView:
orthoState.elevation = 90f; // 90 or 고정값
orthoState.elevation = 90f; // 90 or <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
orthoState.distance = 60f;
orthoState.azimuth = 0f;
orthoState.pivotPosition = Vector3.zero;
@@ -352,18 +354,64 @@ namespace OCTOPUS_TWIN
throw new NotImplementedException();
}
public void AnimateToState(Vector3 pivotPosition, Vector3 eulerAngles, float distance, float duration = 0.4f)
public void SetRoute(CameraRoute route)
{
// 애니메이션 중에는 마우스 입력 비활성화
StopRoute();
Enable = false;
// DoTween을 사용하여 컨트롤러의 상태 값들을 부드럽게 변경
routeSequence = DOTween.Sequence();
for (int i = 0; i < route.PointCount; i++)
{
var (position, point) = route.GetWaypoint(i);
float elev = point != null ? point.elevation : currentElevation;
float azi = point != null ? point.azimuth : currentAzimuth;
float dist = point != null ? point.distance : currentDistance;
float dur = point != null ? point.duration : 0.5f;
float wait = point != null ? point.waitTime : 0f;
routeSequence.Append(
DOTween.To(() => nextPosition, x => nextPosition = x, position, dur));
routeSequence.Join(
DOTween.To(() => currentElevation, x => currentElevation = x, elev, dur));
routeSequence.Join(
DOTween.To(() => currentAzimuth, x => currentAzimuth = x, azi, dur));
routeSequence.Join(
DOTween.To(() => currentDistance, x => currentDistance = x, dist, dur));
if (wait > 0f)
routeSequence.AppendInterval(wait);
}
if (route.loop)
routeSequence.SetLoops(-1, LoopType.Restart);
routeSequence.OnUpdate(LastPositioning);
routeSequence.OnKill(() => Enable = true);
}
public void StopRoute()
{
if (routeSequence != null && routeSequence.IsActive())
{
routeSequence.Kill();
routeSequence = null;
}
}
public void AnimateToState(Vector3 pivotPosition, Vector3 eulerAngles, float distance, float duration = 0.4f)
{
// <20>ִϸ<D6B4><CFB8>̼<EFBFBD> <20>߿<EFBFBD><DFBF><EFBFBD> <20><><EFBFBD><20>Է<EFBFBD> <20><>Ȱ<EFBFBD><C8B0>ȭ
Enable = false;
// DoTween<65><6E> <20><><EFBFBD><EFBFBD>Ͽ<EFBFBD> <20><>Ʈ<EFBFBD>ѷ<EFBFBD><D1B7><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ε巴<CEB5><E5B7B4> <20><><EFBFBD><EFBFBD>
DOTween.To(() => nextPosition, x => nextPosition = x, pivotPosition, duration);
DOTween.To(() => currentElevation, x => currentElevation = x, eulerAngles.x, duration);
DOTween.To(() => currentAzimuth, x => currentAzimuth = x, eulerAngles.y, duration);
DOTween.To(() => currentDistance, x => currentDistance = x, distance, duration)
.OnComplete(() => {
// 애니메이션이 끝나면 마우스 입력을 다시 활성화
// <EFBFBD>ִϸ<EFBFBD><EFBFBD>̼<EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><20>Է<EFBFBD><D4B7><EFBFBD> <20>ٽ<EFBFBD> Ȱ<><C8B0>ȭ
Enable = true;
});
}