Files
XRLib/Assets/Scripts/UVC/Factory/AGVManager.cs
2025-06-20 17:37:20 +09:00

161 lines
5.1 KiB
C#

#nullable enable
using Cysharp.Threading.Tasks;
using SampleProject;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using UnityEngine;
using UVC.Core;
using UVC.Data;
namespace UVC.Factory
{
public class AGVManager : SingletonScene<AGVManager>
{
private readonly string prefabPath = "Prefabs/SampleProject/Factory/AGV";
private GameObject? prefab;
private List<AGV> agvList;
/// <summary>
/// AGVManager의 초기화 메서드입니다.
/// Awake 메서드에서 호출되며, MonoBehaviour가 생성될 때 한 번만 실행됩니다.
/// </summary>
protected override void Init()
{
agvList = new List<AGV>();
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();
}
/// <summary>
/// 기존 데이터와 비교하여 변경된 부분만 전달 됩니다.
/// </summary>
/// <param name="data"></param>
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)
{
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.transform.position = new Vector3(
item.GetFloat("X") * .001f,
0,
item.GetFloat("Y") * .001f
);
agv.transform.rotation = Quaternion.Euler(0, item.GetFloat("DEGREE"), 0);
}
}
}
private async UniTask<AGV?> CreateAGV(DataObject data)
{
if(prefab == null)
{
prefab = await Resources.LoadAsync<GameObject>(prefabPath) as GameObject;
if (prefab == null)
{
Debug.LogError($"Prefab not found at path: {prefabPath}");
return null;
}
}
GameObject prefabInstance = Instantiate(prefab, transform);
Debug.Log($"AGVManager: prefabInstance == null {prefabInstance == null}");
if (prefabInstance == null)
{
Debug.LogError("Failed to instantiate AGV prefab.");
return null;
}
var agv = prefabInstance.GetComponent<AGV>();
agv.Info = new FactoryObjectInfo(
data.GetString("VHL_NAME"),
data.GetString("NODE_ID"),
"",
"",
data.GetString("MODE")
);
agv.transform.position = new Vector3(
data.GetFloat("X") * .001f,
0,
data.GetFloat("Y") * .001f
);
agv.transform.rotation = Quaternion.Euler(0, data.GetFloat("DEGREE"), 0);
return agv;
}
protected override void OnDestroy()
{
base.OnDestroy();
AppMain.Instance.MQTTPipeLine.Remove("AGV");
}
}
}