130 lines
5.7 KiB
C#
130 lines
5.7 KiB
C#
|
|
using System.Collections.Generic;
|
|||
|
|
using UnityEngine;
|
|||
|
|
using UnityEngine.EventSystems;
|
|||
|
|
using UVC.Data;
|
|||
|
|
|
|||
|
|
namespace UVC.Factory.Component
|
|||
|
|
{
|
|||
|
|
public class AGV : FactoryObject
|
|||
|
|
{
|
|||
|
|
private float scaleFactor = 0.0005f; // Unity에서 사용하는 단위로 변환하기 위한 스케일 팩터
|
|||
|
|
|
|||
|
|
// 목표 위치와 회전 값
|
|||
|
|
private Vector3 targetPosition;
|
|||
|
|
private Quaternion targetRotation;
|
|||
|
|
|
|||
|
|
// 움직임과 회전의 부드러움을 조절할 속도 변수
|
|||
|
|
// Unity 인스펙터 창에서 실시간으로 값을 조절하며 테스트할 수 있습니다.
|
|||
|
|
[Tooltip("목표 지점까지의 이동 속도를 조절합니다.")]
|
|||
|
|
public float moveSpeed = 2.0f;
|
|||
|
|
|
|||
|
|
[Tooltip("목표 방향까지의 회전 속도를 조절합니다.")]
|
|||
|
|
public float rotationSpeed = 5.0f;
|
|||
|
|
|
|||
|
|
[Tooltip("이 거리(미터)를 초과하면 보간 없이 즉시 위치를 변경합니다.")]
|
|||
|
|
public float teleportDistanceThreshold = 5.0f; // 5미터 이상 차이나면 순간이동
|
|||
|
|
|
|||
|
|
private void Start()
|
|||
|
|
{
|
|||
|
|
DataOrderedMask = new List<string>
|
|||
|
|
{
|
|||
|
|
"Name",
|
|||
|
|
"Type",
|
|||
|
|
"Status",
|
|||
|
|
"BatteryLevel",
|
|||
|
|
"Location",
|
|||
|
|
"LastMaintenance"
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public override void OnPointerClick(PointerEventData eventData)
|
|||
|
|
{
|
|||
|
|
Debug.Log($"OnPointerClick3: {gameObject.name}");
|
|||
|
|
base.OnPointerClick(eventData);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 내부 상태를 업데이트하고 정렬된 마스크에 정의된 특정 키에 대한 작업을 수행하여 제공된 데이터 객체를 처리합니다.
|
|||
|
|
// </summary>
|
|||
|
|
/// <remarks>이 메서드는 초기화되지 않은 경우 내부 데이터 상태를 업데이트하고, 제공된
|
|||
|
|
/// <see cref="DataOrderedMask"/>에 정의된 키를 반복하여 제공된
|
|||
|
|
/// <paramref name="newData"/> 객체의 일치하는 항목에 대한 작업을 수행합니다. <paramref name="newData"/>에 처리에 필요한 키가 포함되어 있는지
|
|||
|
|
/// 확인합니다.</remarks>
|
|||
|
|
/// <param name="newData">처리할 데이터 객체입니다. null이 아니어야 하며 정렬된 마스크와 관련된 키-값 쌍을 포함해야 합니다.
|
|||
|
|
protected override void ProcessData(DataObject newData)
|
|||
|
|
{
|
|||
|
|
if (data == null)
|
|||
|
|
{
|
|||
|
|
UpdatePositionAndRotation(newData);
|
|||
|
|
data = newData;
|
|||
|
|
// 시작 시에는 현재 위치를 목표 위치로 설정하여 움직이지 않도록 합니다.
|
|||
|
|
targetPosition = transform.position;
|
|||
|
|
targetRotation = transform.rotation;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
UpdatePositionAndRotation(newData);
|
|||
|
|
foreach (var keyValue in newData)
|
|||
|
|
{
|
|||
|
|
if (data.ContainsKey(keyValue.Key))
|
|||
|
|
{
|
|||
|
|
data[keyValue.Key] = keyValue.Value;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void UpdatePositionAndRotation(DataObject newData)
|
|||
|
|
{
|
|||
|
|
if (data == null)
|
|||
|
|
{
|
|||
|
|
float x = newData.GetFloat("X") * scaleFactor;
|
|||
|
|
float y = newData.GetFloat("Y") * scaleFactor;
|
|||
|
|
Quaternion rotation = Quaternion.Euler(0, newData.GetFloat("DEGREE"), 0);
|
|||
|
|
transform.position = new Vector3(x, 0, y);
|
|||
|
|
transform.rotation = rotation;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
float x = data.GetFloat("X") * scaleFactor;
|
|||
|
|
float y = data.GetFloat("Y") * scaleFactor;
|
|||
|
|
Quaternion rotation = Quaternion.Euler(0, data.GetFloat("DEGREE"), 0);
|
|||
|
|
float newX = newData.GetFloat("X") * scaleFactor;
|
|||
|
|
float newY = newData.GetFloat("Y") * scaleFactor;
|
|||
|
|
Quaternion newRotation = Quaternion.Euler(0, newData.GetFloat("DEGREE"), 0);
|
|||
|
|
|
|||
|
|
Vector3 newTargetPosition = new Vector3(x, transform.position.y, y);
|
|||
|
|
Quaternion newTargetRotation = rotation;
|
|||
|
|
|
|||
|
|
if (x != newX || y != newY) newTargetPosition = new Vector3(newX, transform.position.y, newY);
|
|||
|
|
if (rotation != newRotation) newTargetRotation = newRotation;
|
|||
|
|
|
|||
|
|
// 현재 위치와 새로운 목표 위치 사이의 거리를 계산합니다.
|
|||
|
|
float distanceToTarget = Vector3.Distance(transform.position, newTargetPosition);
|
|||
|
|
|
|||
|
|
// 거리가 설정된 임계값을 초과하면, 보간을 건너뛰고 즉시 위치/회전을 설정합니다.
|
|||
|
|
if (distanceToTarget > teleportDistanceThreshold)
|
|||
|
|
{
|
|||
|
|
transform.position = newTargetPosition;
|
|||
|
|
transform.rotation = newTargetRotation;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 새로운 목표 지점을 설정합니다.
|
|||
|
|
// (순간이동을 했든 안 했든, 다음 프레임부터의 보간을 위해 목표 지점은 항상 갱신되어야 합니다.)
|
|||
|
|
this.targetPosition = newTargetPosition;
|
|||
|
|
this.targetRotation = newTargetRotation;
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void Update()
|
|||
|
|
{
|
|||
|
|
// 매 프레임마다 현재 위치에서 목표 위치로 부드럽게 이동시킵니다.
|
|||
|
|
transform.position = Vector3.Lerp(transform.position, targetPosition, Time.deltaTime * moveSpeed);
|
|||
|
|
|
|||
|
|
// 매 프레임마다 현재 회전에서 목표 회전으로 부드럽게 회전시킵니다.
|
|||
|
|
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * rotationSpeed);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|