#nullable enable using Cysharp.Threading.Tasks; using SampleProject; using System; using System.Collections.Generic; using System.Linq; using UnityEngine; using UVC.Core; using UVC.Data; namespace UVC.Factory.Component { public class AGVManager : SingletonScene { private readonly string prefabPath = "Prefabs/SampleProject/Factory/AGV"; private GameObject? prefab; private List agvList; /// /// AGVManager의 초기화 메서드입니다. /// Awake 메서드에서 호출되며, MonoBehaviour가 생성될 때 한 번만 실행됩니다. /// protected override void Init() { agvList = new List(); SceneMain.Instance.Initialized += OnSceneInitialized; } private void OnSceneInitialized() { //데이터를 어떤 형식으로 받을지 정의합니다. var dataMask = new DataMask(); dataMask["VHL_NAME"] = ""; dataMask["AGV_IDX"] = ""; dataMask["B_INSTALL"] = ""; dataMask["NODE_ID"] = ""; dataMask["REAL_ID"] = ""; dataMask["VHL_STATE"] = ""; dataMask["BAY_LIST"] = ""; dataMask["X"] = 0; dataMask["Y"] = 0; dataMask["DEGREE"] = 0.0; dataMask["MODE"] = ""; dataMask["BATT"] = ""; dataMask["SUB_GOAL"] = ""; dataMask["FINAL_GOAL"] = ""; dataMask["JOB_ID"] = ""; dataMask["TIMESTAMP"] = DateTime.Now; var pipelineInfo = new MQTTPipeLineInfo("AGV") .setDataMapper(new DataMapper(dataMask)) .setHandler(OnUpdateData); // MQTTPipeLine에 파이프라인 정보를 추가합니다. AppMain.Instance.MQTTPipeLine.Add(pipelineInfo); } public void OnUpdateData(IDataObject? data) { OnUpdateDataAsync(data).Forget(); } /// /// 기존 데이터와 비교하여 변경된 부분만 전달 됩니다. /// /// public async UniTask OnUpdateDataAsync(IDataObject? data) { if (data == null) return; DataArray? arr = data as DataArray; if (arr == null || arr.Count == 0) return; var AddedItems = arr.AddedItems; var RemovedItems = arr.RemovedItems; var ModifiedList = arr.ModifiedList; foreach (var item in AddedItems.ToList()) { AGV? agv = await CreateAGV(item); if (agv != null) { agv.UpdateData(item); agvList.Add(agv); } } foreach (var item in RemovedItems.ToList()) { AGV agv = agvList.Find(x => x.Info != null && x.Info.Name == item.GetString("VHL_NAME")); if (agv != null) { Destroy(agv.gameObject); agvList.Remove(agv); } } foreach (var item in ModifiedList.ToList()) { AGV agv = agvList.Find(x => x.Info != null && x.Info.Name == item.GetString("VHL_NAME")); if (agv != null) { agv.UpdateData(item); } } } private async UniTask CreateAGV(DataObject data) { if (prefab == null) { prefab = await Resources.LoadAsync(prefabPath) as GameObject; if (prefab == null) { Debug.LogError($"Prefab not found at path: {prefabPath}"); return null; } } GameObject prefabInstance = Instantiate(prefab, transform); if (prefabInstance == null) { Debug.LogError("Failed to instantiate AGV prefab."); return null; } var agv = prefabInstance.GetComponent(); agv.Info = new FactoryObjectInfo( data.GetString("VHL_NAME"), data.GetString("NODE_ID"), "", "", data.GetString("MODE") ); return agv; } protected override void OnDestroy() { base.OnDestroy(); AppMain.Instance.MQTTPipeLine.Remove("AGV"); } } }