using Gpm.Ui.Sample; using System.Collections.Generic; using TMPro; using Unity.VisualScripting; using UnityEngine; using UnityEngine.SocialPlatforms; using UVC.Data.Core; namespace Simulator.Data.Transport { public class AGV : ComponentBase { private Vector3 targetPosition; private Vector3 startPosition; private Quaternion targetRotation; private float moveSpeed; private float t = 0f; public GameObject entitySocket; public List possessEntities = new List(); int index = 0; public AGVData data; bool getdata = false; public void UpdatePosition(Vector3 position) { transform.position = position; } public void SetTargetPosition(DataObject agvData) { var datas = agvData.GetDataObject("data"); var timing = datas.GetDataObject("timing"); var duration = timing.GetDataObject("duration"); targetPosition = AGVNodeManager.Instance.GetNodePosition(datas.GetString("to_node")); startPosition = AGVNodeManager.Instance.GetNodePosition(datas.GetString("from_node")); moveSpeed = (float)duration.GetFloat("real_seconds"); t = 0f; getdata = true; //Debug.Log($"{datas.GetDateTime("timestamp").ToString()}{index}{data.name},from:{datas.GetString("from_node")},to:{datas.GetString("to_node")}"); //Debug.Log($"move{agvData.GetString("component_id")}"); } private void PlaceNext(Entity entity) { if (entity == null) return; if (entitySocket == null) { Debug.LogWarning("[AGV] entitySocket 이 null 입니다. 배치를 건너뜁니다."); return; } // 부모/로컬 트랜스폼 설정 entity.transform.SetParent(entitySocket.transform, worldPositionStays: false); // Z 방향 적층(기존 로직 유지) float stepZ = EntityManager.Instance.ObjectSize.z; entity.transform.localPosition = new Vector3(0f, 0f, stepZ * index); Debug.Log(stepZ); Debug.Log(index); entity.transform.localRotation = Quaternion.identity; // 중복 방지 후 등록 if (!possessEntities.Contains(entity)) possessEntities.Add(entity); index++; } public void LoadEntity(DataObject agvData) { var datas = agvData.GetDataObject("data"); var entityIds = datas["entity_ids"].ConvertTo>(); if (entityIds == null || entityIds.Count == 0) return; var entities = EntityManager.Instance.GetEntities(entityIds, this); if (entities == null || entities.Count == 0) return; foreach (var e in entities) { PlaceNext(e); } } public override void DecreaseEntity(Entity entity) { if (entity == null) return; // 내부 리스트에서 제거(부모 변경/파괴 등 어떤 상태든 Remove는 안전) possessEntities.Remove(entity); // 재배치 ReflowEntities(); } /// /// 현재 보유 엔티티들을 0번 인덱스부터 다시 적층하여 빈칸 제거 /// 순회-수정 예외 방지를 위해 스냅샷을 만든 뒤, 원본을 비우고 다시 채움 /// public void ReflowEntities() { // 위치 인덱스 초기화 index = 0; // 스냅샷 생성 (null 제거) var snapshot = new List(possessEntities.Count); foreach (var e in possessEntities) { if (e != null) snapshot.Add(e); } // 원본을 비운 뒤 스냅샷 기반으로 재배치 possessEntities.Clear(); foreach (var e in snapshot) { PlaceNext(e); } } void Update() { if (getdata) { if (moveSpeed <= 0f) return; t += Time.deltaTime / moveSpeed; // 위치 업데이트 if (t <= 1f) { transform.position = Vector3.Lerp(startPosition, targetPosition, t); } else { transform.position = targetPosition; getdata = false; } } /* // 회전 업데이트 if (isRotating) { float currentAngle = transform.eulerAngles.y; float targetAngle = targetRotation.eulerAngles.y; float newAngle = Mathf.SmoothDampAngle(currentAngle, targetAngle, ref angularVelocity, rotationSpeed, Mathf.Infinity, dampedTime); transform.rotation = Quaternion.Euler(0, newAngle, 0); } else { transform.rotation = targetRotation; angularVelocity = 0f; } */ } } }