Files
Simulation/Assets/Scripts/SimulationModels/SimulationModelMove.cs

469 lines
13 KiB
C#
Raw Normal View History

2025-08-04 17:26:24 +09:00
using UnityEngine;
2025-06-24 17:02:07 +09:00
using System;
2025-05-27 14:53:01 +09:00
using System.Collections.Generic;
2025-05-28 10:08:15 +09:00
using UnityEngine.Events;
2025-06-04 18:30:27 +09:00
using Octopus.Simulator.Networks;
2025-06-24 17:02:07 +09:00
using Newtonsoft.Json;
2025-07-22 14:03:40 +09:00
using Octopus.Simulator;
2025-06-24 17:02:07 +09:00
2025-08-04 17:26:24 +09:00
#region class
2025-06-24 17:02:07 +09:00
[Serializable]
public class MoveDataClass_start
{
public string move_id;
public string move_label;
public string type;
public float move_time;
public int capacity;
public int products_per_batch;
public List<InputQueue> input_queues;
public string output_queue;
public string defect_queue;
public string required_resource;
public float return_time;
public int min_batch_size;
public float loading_delay;
public float unloading_delay;
}
[Serializable]
public class MoveDataClass_loading
{
public string move_id;
public string move_label;
public int loaded_count;
public List<string> source_queues;
public List<string> source_stores;
public float loading_delay;
}
[Serializable]
public class MoveDataClass_Request_Resource
{
public string move_id;
public string move_label;
}
[Serializable]
public class MoveDataClass_Resource_Acquired
{
public string resource;
}
[Serializable]
public class MoveDataClass_Speed_Factor_Applied
{
public float original;
public float adjusted;
}
[Serializable]
public class MoveDataClass_Move_Moving
{
public float time;
public float loading_delay;
public float unloading_delay;
public MoveMovingInput input;
public MoveMovingOutput output;
}
[Serializable]
public class MoveMovingInput
{
public List<string> queues;
public List<string> stores;
}
[Serializable]
public class MoveMovingOutput
{
public string queue;
public string store;
public string defect_queue;
public string defect_store;
}
[Serializable]
public class MoveDataClass_Arrived
{
public int count;
}
[Serializable]
public class MoveDataClass_Unloading_Defect
{
public string product_id;
public string output_queue;
public int output_queue_length;
public float unloading_delay;
}
2025-07-14 09:35:27 +09:00
[Serializable]
public class MoveDataClass_Unloading_Defect_Store
{
public string product_id;
public string store_name;
public int store_length;
public float unloading_delay;
}
2025-06-24 17:02:07 +09:00
[Serializable]
public class MoveDataClass_Unloading
{
public string product_id;
public string output_queue;
public int output_queue_length;
public float unloading_delay;
}
[Serializable]
public class MoveDataClass_Unloading_Store
{
public string product_id;
2025-07-14 09:35:27 +09:00
public string store_name;
2025-06-24 17:02:07 +09:00
public int store_queue_length;
public float unloading_delay;
}
[Serializable]
public class MoveDataClass_returning
{
public float return_time;
}
2025-06-04 18:30:27 +09:00
2025-07-15 17:35:53 +09:00
[Serializable]
public class MoveDataClassStatistics
{
public statisticsMove statistics;
}
[Serializable]
public class statisticsMove
{
public int total_moved;
}
2025-09-08 12:03:11 +09:00
public enum UnLoadingState
{
store,
queue,
defectStore,
defectQueue
}
2025-08-04 17:26:24 +09:00
#endregion
2025-07-15 17:35:53 +09:00
2025-05-27 14:53:01 +09:00
public class SimulationModelMove : SimulationModel
2025-05-26 18:06:25 +09:00
{
2025-08-04 17:26:24 +09:00
[Header("Transport")]
2025-05-27 14:53:01 +09:00
public List<GameObject> listProducts = new List<GameObject>();
public Transform productPos;
public Vector3 productDistance = new Vector3(0, 0.321f, 0);
2025-08-04 17:26:24 +09:00
2025-05-27 14:53:01 +09:00
int productCount = 0;
2025-07-22 14:03:40 +09:00
int currentCount = 0;
int totalMoved = 0;
2025-08-04 17:26:24 +09:00
bool isFirstTransport = true;
2025-05-27 14:53:01 +09:00
Transform origin = null;
2025-07-08 13:42:26 +09:00
public Transform destination = null;
2025-08-04 17:26:24 +09:00
2025-07-08 13:42:26 +09:00
public float arrivalTime = 0;
public float elapsedTime = 0;
2025-08-04 17:26:24 +09:00
2025-05-27 14:53:01 +09:00
Vector3 originalPos;
Vector3 prevPos;
2025-05-29 09:25:40 +09:00
2025-05-27 14:53:01 +09:00
void Update()
2025-05-26 18:06:25 +09:00
{
2025-08-04 17:26:24 +09:00
if (!simulationUI.isplaying)
return;
UpdateProductStacking();
UpdateMovement();
}
private void UpdateProductStacking()
{
if (productCount != listProducts.Count)
2025-05-27 14:53:01 +09:00
{
2025-08-04 17:26:24 +09:00
productCount = listProducts.Count;
// 단순하게 모두 같은 offset으로 배치 (필요 시 i 기반 offset으로 확장)
foreach (var gb in listProducts)
2025-05-27 14:53:01 +09:00
{
2025-08-04 17:26:24 +09:00
if (gb != null)
2025-07-18 14:42:37 +09:00
{
gb.transform.localPosition = productDistance;
}
2025-05-27 14:53:01 +09:00
}
}
2025-05-26 18:06:25 +09:00
}
2025-07-22 18:25:07 +09:00
2025-08-04 17:26:24 +09:00
private void UpdateMovement()
2025-06-24 17:02:07 +09:00
{
2025-08-04 17:26:24 +09:00
if (destination == null)
return;
2025-07-22 14:03:40 +09:00
2025-08-04 17:26:24 +09:00
elapsedTime += Time.deltaTime * WebParameters.speed;
2025-07-22 18:25:07 +09:00
2025-08-04 17:26:24 +09:00
if (arrivalTime <= 0f)
return;
2025-07-22 18:25:07 +09:00
2025-08-04 17:26:24 +09:00
float t = elapsedTime / arrivalTime;
if (t > 1f)
{
transform.position = destination.position;
transform.forward = destination.forward;
destination = null;
}
else
{
Vector3 newPos = Vector3.Lerp(originalPos, destination.position, t);
transform.position = newPos;
2025-07-22 18:25:07 +09:00
2025-08-04 17:26:24 +09:00
Vector3 dir = newPos - prevPos;
dir.y = 0;
if (dir.sqrMagnitude > 0.0001f)
2025-06-24 17:02:07 +09:00
{
2025-08-04 17:26:24 +09:00
dir.Normalize();
transform.forward = dir;
}
2025-07-22 18:25:07 +09:00
2025-08-04 17:26:24 +09:00
prevPos = newPos;
}
}
2025-07-22 18:25:07 +09:00
2025-08-04 17:26:24 +09:00
public override void GetData(string data)
{
var wrapclass = JsonConvert.DeserializeObject<SimulationDefaultJson>(data);
if (wrapclass == null || string.IsNullOrEmpty(wrapclass._event))
return;
2025-09-08 12:03:11 +09:00
2025-08-04 17:26:24 +09:00
switch (wrapclass._event)
{
case "move_loading":
LoadingCargo(wrapclass.data.ToString());
2025-09-08 12:03:11 +09:00
break;
2025-08-04 17:26:24 +09:00
case "move_moving":
Moving(wrapclass.data.ToString());
2025-09-08 12:03:11 +09:00
break;
2025-08-04 17:26:24 +09:00
case "move_unloading":
2025-09-08 12:03:11 +09:00
Unloading(wrapclass.data.ToString(), UnLoadingState.queue);
break;
case "move_unloading_store":
Unloading(wrapclass.data.ToString(), UnLoadingState.store);
break;
case "move_unloading_defect":
Unloading(wrapclass.data.ToString(), UnLoadingState.defectQueue);
break;
case "move_unloading_defect_store":
Unloading(wrapclass.data.ToString(), UnLoadingState.defectStore);
break;
case "move_arrived":
Arrive(wrapclass.data.ToString());
break;
2025-08-04 17:26:24 +09:00
case "move_speed_factor_applied":
2025-09-08 12:03:11 +09:00
SpeedFactorApply(wrapclass.data.ToString());
break;
2025-08-04 17:26:24 +09:00
case "move_returning":
2025-09-08 12:03:11 +09:00
Returning(wrapclass.data.ToString());
break;
case "move_statistics_update":
totalMoved = JsonConvert.DeserializeObject<MoveDataClassStatistics>(wrapclass.data.ToString()).statistics.total_moved;
SetBubble(totalMoved);
2025-08-04 17:26:24 +09:00
break;
2025-07-15 17:35:53 +09:00
}
}
2025-08-04 17:26:24 +09:00
private void LoadingCargo(string data)
{
var loading = JsonConvert.DeserializeObject<MoveDataClass_loading>(data);
if (loading == null)
return;
currentCount = loading.loaded_count;
SetBubble(currentCount);
// 처음 운송이면 출발 위치 세팅
if (isFirstTransport)
{
string sourceId = GetFirstNonEmpty(loading.source_queues, loading.source_stores);
if (!string.IsNullOrEmpty(sourceId))
{
var sourceModel = DataManager.I.GetModel(sourceId) as SimulationModelStore;
if (sourceModel != null)
{
transform.position = sourceModel.GetTransporterPosition()?.position ?? transform.position;
}
}
isFirstTransport = false;
}
AddProducts(loading.loaded_count);
}
private void Moving(string data)
{
var moveData = JsonConvert.DeserializeObject<MoveDataClass_Move_Moving>(data);
if (moveData == null)
return;
elapsedTime = 0f;
arrivalTime = moveData.time;
originalPos = transform.position;
prevPos = transform.position;
string inputId = GetFirstNonEmpty(moveData.input?.queues, moveData.input?.stores);
if (!string.IsNullOrEmpty(inputId))
{
var model = DataManager.I.GetModel(inputId) as SimulationModelStore;
if (model != null)
origin = model.GetTransporterPosition();
}
if (!string.IsNullOrEmpty(moveData.output?.queue))
{
var model = DataManager.I.GetModel(moveData.output.queue) as SimulationModelStore;
if (model != null)
destination = model.GetTransporterPosition();
}
else if (!string.IsNullOrEmpty(moveData.output?.store))
{
var model = DataManager.I.GetModel(moveData.output.store) as SimulationModelStore;
if (model != null)
destination = model.GetTransporterPosition();
}
}
private string GetFirstNonEmpty(List<string> listA, List<string> listB)
{
if (listA != null && listA.Count > 0)
return listA[0];
if (listB != null && listB.Count > 0)
return listB[0];
return string.Empty;
}
private void AddProducts(int count)
{
for (int i = 0; i < count; i++)
{
var product = ProductManager.Instance.SpawnProduct();
if (product == null)
continue;
product.GetComponent<SimulationModelProduct>().SetParent(this.nodeID);
product.transform.parent = productPos;
product.transform.localPosition = Vector3.zero;
product.transform.localRotation = Quaternion.identity;
listProducts.Add(product);
}
}
2025-09-08 12:03:11 +09:00
private void Unloading(string data, UnLoadingState state)
{
string targetID = string.Empty;
switch (state)
{
case UnLoadingState.store:
var store = JsonConvert.DeserializeObject<MoveDataClass_Unloading_Store>(data);
targetID = store?.store_name ?? string.Empty;
break;
case UnLoadingState.queue:
var queue = JsonConvert.DeserializeObject<MoveDataClass_Unloading>(data);
targetID = queue?.output_queue ?? string.Empty;
break;
case UnLoadingState.defectStore:
var defectStore = JsonConvert.DeserializeObject<MoveDataClass_Unloading_Defect_Store>(data);
targetID = defectStore?.store_name ?? string.Empty;
break;
case UnLoadingState.defectQueue:
var defectQueue = JsonConvert.DeserializeObject<MoveDataClass_Unloading_Defect>(data);
targetID = defectQueue?.output_queue ?? string.Empty;
break;
}
if (string.IsNullOrEmpty(targetID))
return;
var model = DataManager.I.GetModel(targetID);
if (model == null)
{
return;
}
var storeModel = model.GetComponent<SimulationModelStore>();
if (listProducts.Count > 0)
{
var product = listProducts[0];
// storeModel?.StoreProduct(product); // 필요 시 활성화
listProducts.RemoveAt(0);
Destroy(product);
}
else
{
Debug.LogWarning("Trying to unload from empty transporter : " + nodeID);
}
}
private void Arrive(string data)
{
var arrived = JsonConvert.DeserializeObject<MoveDataClass_Arrived>(data);
if (arrived == null)
return;
currentCount -= arrived.count;
SetBubble(currentCount);
}
private void SpeedFactorApply(string data)
{
var speedData = JsonConvert.DeserializeObject<MoveDataClass_Speed_Factor_Applied>(data);
if (speedData == null)
return;
float originalTime = speedData.original;
float adjustedTime = speedData.adjusted;
arrivalTime += adjustedTime - originalTime;
elapsedTime = 0f;
originalPos = transform.position;
prevPos = transform.position;
}
private void Returning(string data)
{
var ret = JsonConvert.DeserializeObject<MoveDataClass_returning>(data);
if (ret == null)
return;
elapsedTime = 0f;
arrivalTime = ret.return_time;
originalPos = transform.position;
prevPos = transform.position;
if (origin != null)
destination = origin;
}
2025-07-15 17:35:53 +09:00
public override void SetBubble(object data)
{
2025-07-22 14:03:40 +09:00
string msg = $"{currentCount}/{totalMoved}";
2025-07-15 17:35:53 +09:00
if (currentBubble == null)
{
// 생성
2025-07-15 17:35:53 +09:00
currentBubble = Instantiate(bubbleUIPrefab, FindAnyObjectByType<Canvas_Bubble>().transform);
currentBubble.target = DataBubbleSocket;
currentBubble.worldOffset = new Vector3(0, 2.0f, 0); // 필요에 따라 조절
2025-07-22 15:57:29 +09:00
currentBubble.GetComponent<RectTransform>().SetAsFirstSibling();
2025-07-15 17:35:53 +09:00
}
// 텍스트 갱신
2025-07-15 17:35:53 +09:00
currentBubble.SetMessage(msg);
2025-07-22 14:03:40 +09:00
List<string> datas = new List<string>
{
currentCount.ToString(),
totalMoved.ToString()
};
2025-07-22 15:57:29 +09:00
currentBubble.SetDetail(datas, logicType.move, LogicUIManager.instance.GetItemLabelByID(nodeID));
2025-06-24 17:02:07 +09:00
}
2025-05-26 18:06:25 +09:00
}