3d complete

This commit is contained in:
2025-12-11 18:26:09 +09:00
parent 8a2ffed689
commit d600885302
99 changed files with 9933 additions and 2170 deletions

View File

@@ -136,11 +136,12 @@ namespace Simulator.Data.Transport
{
switch (type)
{
case "AGV":
case "agv":
var agv = agvPool.GetItem($"{data.name}");
agv.data = data;
agv.UpdatePosition(AGVNodeManager.Instance.GetNodePosition(data.initial_node));
agvMap.Add(data.name, agv);
Debug.Log(data.name);
break;
case "afl":
var afl = aflPool.GetItem($"{data.name}");

View File

@@ -12,7 +12,9 @@ public enum ComponentType
Rack,
Queue,
ASRS,
RobotArm
RobotArm,
Processor,
Worker
}
public class ComponentBase : MonoBehaviour,IPointerClickHandler
{

View File

@@ -25,6 +25,8 @@ namespace Simulator.Data
{"sink","prefabs/Sink_Container"},
{"asrs","prefabs/ASRS"},
{"robotArm","prefabs/RobotArm"},
{"processor","prefabs/Processor"},
{"worker","prefabs/Worker"}
};
public Dictionary<string, ComponentBase> componentDatas = new Dictionary<string, ComponentBase>();
@@ -36,6 +38,8 @@ namespace Simulator.Data
private GameObjectPool<RackComponent>? rackPool;
private GameObjectPool<ASRSComponent>? asrsPool;
private GameObjectPool<RobotArmComponent>? robotArmPool;
private GameObjectPool<ProcessorComponent>? processorPool;
private GameObjectPool<WorkerComponent>? workerPool;
public LogicDetailData logicDetailData;
public SimulatorCodeDataClass codedata;
@@ -113,6 +117,30 @@ namespace Simulator.Data
}
}
public GameObjectPool<ProcessorComponent> ProcessorPool
{
get
{
if (processorPool == null)
{
Debug.LogError("Pool is not initialized. Please call InitializePoolAsync first.");
}
return processorPool!;
}
}
public GameObjectPool<WorkerComponent> WorkerPool
{
get
{
if (workerPool == null)
{
Debug.LogError("Pool is not initialized. Please call InitializePoolAsync first.");
}
return workerPool!;
}
}
protected override void Init()
{
InitializeSourcePoolAsync().ContinueWith(() =>
@@ -199,6 +227,18 @@ namespace Simulator.Data
DataMapper robotArmMapper = new DataMapper(robotArmDataMask);
dataMapperDict.Add(ComponentType.RobotArm, robotArmMapper);
});
InitializeProcessorPoolAsync().ContinueWith(() =>
{
var processorDataMask = new DataMask();
DataMapper processorMapper = new DataMapper(processorDataMask);
dataMapperDict.Add(ComponentType.Processor, processorMapper);
});
InitializeWorkerPoolAsync().ContinueWith(() =>
{
var workerDataMask = new DataMask();
DataMapper workermapper = new DataMapper(workerDataMask);
dataMapperDict.Add(ComponentType.Worker, workermapper);
});
//testRequest();
}
@@ -208,6 +248,13 @@ namespace Simulator.Data
logicDetailData = data.data.data;
onProjectNameRecieved?.Invoke(data.data.name);
SpawnComponents(data.data.data);
if (logicDetailData.templates != null)
{
if (logicDetailData.templates.prefabs.Count >= 1)
{
PrefabManager.Instance.SetPrefabs(logicDetailData.templates.prefabs);
}
}
if (logicDetailData.transport_system != null)
{
if (logicDetailData.transport_system.node_networks != null && logicDetailData.transport_system.node_networks.Count >= 1)
@@ -313,6 +360,14 @@ namespace Simulator.Data
RobotArmComponent? robotArm = robotArmPool.GetItem(obj.GetString("component_id")!);
robotArm.GetModelData(obj);
break;
case ComponentType.Processor:
ProcessorComponent? processor = processorPool.GetItem(obj.GetString("component_id")!);
processor.GetModelData(obj);
break;
case ComponentType.Worker:
WorkerComponent? worker = workerPool.GetItem(obj.GetString("component_id")!);
worker.GetModelData(obj);
break;
}
}
@@ -394,6 +449,32 @@ namespace Simulator.Data
robotArmPool = new GameObjectPool<RobotArmComponent>(prefab, transform);
}
private async UniTask InitializeProcessorPoolAsync()
{
if (processorPool != null) return;
var prefab = await Resources.LoadAsync<GameObject>(prefabPaths["processor"]) as GameObject;
if (prefab == null)
{
Debug.LogError($"Prefab not found at path: {prefabPaths["processor"]}");
return;
}
processorPool = new GameObjectPool<ProcessorComponent>(prefab, transform);
}
private async UniTask InitializeWorkerPoolAsync()
{
if (workerPool != null) return;
var prefab = await Resources.LoadAsync<GameObject>(prefabPaths["worker"]) as GameObject;
if (prefab == null)
{
Debug.LogError($"Prefab not found at path: {prefabPaths["worker"]}");
return;
}
workerPool = new GameObjectPool<WorkerComponent>(prefab, transform);
}
private void SpawnComponents(LogicDetailData data)
{
foreach (var component in data.production_system.sources)
@@ -453,6 +534,29 @@ namespace Simulator.Data
componentDatas.Add(component.name, robotArm);
}
}
if (data.production_system.processors != null)
{
foreach (var component in data.production_system.processors)
{
var processor = processorPool.GetItem($"{component.name}");
processor.componentType = ComponentType.Processor;
processor.SetComponent(component);
processor.SetPosition();
componentDatas.Add(component.name, processor);
}
}
if (data.infrastructure.resources != null)
{
foreach (var component in data.infrastructure.resources)
{
Debug.Log(component.name);
var worker = workerPool.GetItem($"{component.name}");
worker.componentType = ComponentType.Worker;
worker.SetComponent(component);
//worker.SetPosition();
componentDatas.Add(component.name, worker);
}
}
}
}
}

View File

@@ -25,15 +25,23 @@ namespace Simulator.Data
public class LogicDetailData
{
public string name;
public templates templates;
public Infrastructure infrastructure;
public Transport_System transport_system;
public Production_System production_system;
}
[Serializable]
public class templates
{
public List<PrefabData> prefabs;
}
[Serializable]
public class Infrastructure
{
public List<QueueDataClass> queues;
public List<WorkerDataClass> resources;
}
[Serializable]
@@ -77,6 +85,7 @@ namespace Simulator.Data
public List<RackDataClass> racks;
public List<ConveyorDataClass> conveyors;
public List<RobotArmDataClass> robot_arms;
public List<ProcessorDataClass> processors;
}
[Serializable]

View File

@@ -40,6 +40,7 @@ namespace Simulator.Data {
var entity = EntityManager.Instance.GetEntity(entityid, this);
entity.transform.SetParent(cellComponents[(-1, 0, 0)].Socket.transform);
entity.transform.localPosition = new Vector3(0, -0.25f, -0.25f);
entity.transform.localRotation= Quaternion.identity;
entitys.Add(entity.gameObject);
}
@@ -56,8 +57,17 @@ namespace Simulator.Data {
var ty = to_position.GetInt("y").Value;
var tz = to_position.GetInt("z").Value;
Vector3 toVector3 = new Vector3(tx, ty, tz);
var entityIds = datas["entities"].ConvertTo<List<string>>();
var entities=EntityManager.Instance.SpawnEntites(entityIds, this);
//var entityIds = datas["entities"].ConvertTo<List<string>>();
//var entities=EntityManager.Instance.SpawnEntites(entityIds, this);
List<Entity> entities = new List<Entity>();
var entity_Ids = datas.GetDataArray("entity_ids");
foreach (var entity in entity_Ids)
{
var id = entity.GetString("entity_id");
var name = entity.GetString("prefab_name");
entities.Add(EntityManager.Instance.SpawnEntity(id, this, name));
}
int index = 0;
for (int x = fx; x < tx; x++)
{

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 11074ccee8829014b8e2def6ef6b6851
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,46 @@
using Simulator.Data;
using UnityEngine;
using UVC.Data.Core;
public class ProcessorComponent : ComponentBase
{
ProcessorDataClass processorData = new ProcessorDataClass();
[SerializeField]
GameObject Socket;
[SerializeField]
GameObject screen;
Entity entity;
public void SetComponent(ProcessorDataClass processorData)
{
this.processorData = processorData;
data = processorData;
FitCollider();
}
public override void GetModelData(DataObject modelData)
{
var name = modelData.GetString("event_name");
var data = modelData.GetDataObject("data");
switch (name)
{
case "loading":
entity=EntityManager.Instance.GetEntity(data.GetString("entity_id"), this);
entity.transform.parent = Socket.transform;
entity.transform.localPosition = new Vector3(0, 0, 0);
entity.transform.localRotation = Quaternion.identity;
break;
case "started":
screen.SetActive(true);
break;
case "completed":
var prefabs = data.GetDataArray("prefabs");
var prefabName = prefabs[0].GetString("name");
EntityManager.Instance.SetEntity(entity, prefabName);
screen.SetActive(false);
break;
case "unloading":
break;
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 90c6cd274abd7b149807dc2b6899eee3

View File

@@ -0,0 +1,11 @@
using System;
namespace Simulator.Data
{
[Serializable]
public class ProcessorDataClass : ComponentDataBase
{
public string name;
public string label;
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 60ee837c2e5dafa42869bbf71b032306

View File

@@ -13,6 +13,7 @@ public class RobotArmComponent : ComponentBase
GameObject gripper;
public RobotArmDataClass robotArmData;
Entity gripEntity;
Vector3 startPosition;
private Vector3 targetPosition;
@@ -46,9 +47,13 @@ public class RobotArmComponent : ComponentBase
case "loading":
var loadingdatas = modelData.GetDataObject("data");
moveSpeed = (float)loadingdatas.GetFloat("processing_time");
var entity = EntityManager.Instance.GetEntity(loadingdatas.GetString("entity_id"), this);
entity.transform.parent = gripper.transform;
entity.transform.localPosition = new Vector3(-0.25f, 0, 0);
gripEntity = EntityManager.Instance.GetEntity(loadingdatas.GetString("entity_id"), this);
gripEntity.transform.parent = gripper.transform;
gripEntity.transform.localPosition = new Vector3(-0.25f, 0, 0);
break;
case "unloading":
gripEntity.transform.parent = null;
gripEntity = null;
break;
}
}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 690183da8bded214080bb4c9b6cb67bc
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,74 @@
using Gpm.Ui.Sample;
using Simulator.Data;
using Simulator.Data.Transport;
using System.Net.Sockets;
using TMPro;
using UnityEditor.Animations;
using UnityEngine;
using UnityEngine.Device;
using UVC.Data.Core;
public class WorkerComponent : ComponentBase
{
[SerializeField]
AnimatorController walk;
[SerializeField]
AnimatorController working;
[SerializeField]
Animator anim;
bool getData=false;
float moveSpeed;
Vector3 startPosition;
Vector3 targetPosition;
float t;
public void SetComponent(WorkerDataClass data)
{
this.gameObject.SetActive(false);
}
public override void GetModelData(DataObject modelData)
{
var name = modelData.GetString("event_name");
var datas = modelData.GetDataObject("data");
switch (name)
{
case "moving":
this.gameObject.SetActive(true);
var timing = datas.GetDataObject("timing");
var duration = timing.GetDataObject("duration");
targetPosition = ComponentsManager.Instance.componentDatas[datas.GetString("to")].transform.position;
startPosition = ComponentsManager.Instance.componentDatas[datas.GetString("from")].transform.position;
//startPosition = ComponentsManager.Instance.GetNodePosition(datas.GetString("from_node"));
moveSpeed = (float)duration.GetFloat("real_seconds");
t = 0f;
getData = true;
transform.LookAt(targetPosition);
anim.runtimeAnimatorController = walk;
break;
}
}
private 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;
anim.runtimeAnimatorController = working;
}
}
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: ef8351ec4acd1954db197da0a6b5066b

View File

@@ -0,0 +1,9 @@
using Simulator.Data;
using System;
[Serializable]
public class WorkerDataClass : ComponentDataBase
{
public string name;
public string label;
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: a1ff316f7caa56b408fb6fca588d65a5

View File

@@ -74,32 +74,41 @@ namespace Simulator.Data
public override void GetModelData(DataObject modelData)
{
// total_entity 업데이트(참조용)
sourceModelData.total_entity = modelData.GetDataObject("data").GetInt("total_entity") ?? 0;
// entity_ids -> 여러 개 동시 스폰
var datas = modelData.GetDataObject("data");
var entityIds = datas["entity_ids"].ConvertTo<List<string>>();
var entity_Ids = datas.GetDataArray("entity_ids");
if (entityIds == null || entityIds.Count == 0)
foreach (var entity in entity_Ids)
{
Debug.LogWarning("[SourceComponent] entity_ids가 비어있습니다.");
return;
var id = entity.GetString("entity_id");
var name = entity.GetString("prefab_name");
PlaceNext(EntityManager.Instance.SpawnEntity(id, this, name));
}
/*
var entityIds = datas["entity_ids"].ConvertTo<List<string>>();
// 여러 개를 한 번에 스폰
var entities = EntityManager.Instance.SpawnEntites(entityIds, this);
if (entities == null || entities.Count == 0)
{
return;
}
// 배치
foreach (var e in entities)
{
if (e == null) continue;
PlaceNext(e);
}
if (entityIds == null || entityIds.Count == 0)
{
Debug.LogWarning("[SourceComponent] entity_ids가 비어있습니다.");
return;
}
// 여러 개를 한 번에 스폰
var entities = EntityManager.Instance.SpawnEntites(entityIds, this);
if (entities == null || entities.Count == 0)
{
return;
}
// 배치
foreach (var e in entities)
{
if (e == null) continue;
PlaceNext(e);
}
*/
}
public override void DecreaseEntity(Entity entity)

View File

@@ -1,17 +1,26 @@
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
public class Entity : MonoBehaviour
{
public string name;
public MaterialPropertyBlock mpb;
public List<MeshRenderer> renderers;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
void Awake()
{
renderers = GetComponentsInChildren<MeshRenderer>().ToList();
mpb = new MaterialPropertyBlock();
}
// Update is called once per frame
void Update()
public void SetColor(Color color)
{
foreach (var renderer in renderers)
{
mpb.SetColor("_BaseColor", color);
renderer.SetPropertyBlock(mpb);
}
}
}

View File

@@ -16,7 +16,7 @@ public class EntityManager : SingletonScene<EntityManager>
};
private Dictionary<string, Entity> entityDatas = new Dictionary<string, Entity>();
Dictionary<Entity,ComponentBase> possessComponents= new Dictionary<Entity,ComponentBase>();
Dictionary<Entity, ComponentBase> possessComponents = new Dictionary<Entity, ComponentBase>();
public Vector3 ObjectSize;
public event Action<Entity> OnEntityDestroyed;
@@ -52,17 +52,17 @@ public class EntityManager : SingletonScene<EntityManager>
entityPool = new GameObjectPool<Entity>(prefab, transform);
ObjectSize = prefab.GetComponent<MeshFilter>().sharedMesh.bounds.size;
}
public Entity SpawnEntity(string entityName,ComponentBase component)
public Entity SpawnEntity(string entityName, ComponentBase component, string prefabName)
{
//Debug.Log($"spawn{entityName}");
var entity = entityPool.GetItem($"{entityName}");
entity.name = entityName;
SetEntity(entity, prefabName);
entityDatas.Add(entityName, entity);
possessComponents.Add(entity, component);
return entity;
}
public List<Entity> SpawnEntites(List<string> entityNames,ComponentBase component)
public List<Entity> SpawnEntites(List<string> entityNames, ComponentBase component)
{
List<Entity> entities = new List<Entity>();
foreach (var entityName in entityNames)
@@ -74,13 +74,13 @@ public class EntityManager : SingletonScene<EntityManager>
{
entityDatas.Add(entityName, entity);
entities.Add(entity);
possessComponents.Add(entity,component);
possessComponents.Add(entity, component);
}
}
return entities;
}
public Entity GetEntity(string entityName,ComponentBase component)
public Entity GetEntity(string entityName, ComponentBase component, string prefabName = null)
{
if (entityDatas.ContainsKey(entityName))
{
@@ -91,11 +91,11 @@ public class EntityManager : SingletonScene<EntityManager>
}
else
{
return SpawnEntity(entityName,component);
return SpawnEntity(entityName, component, prefabName);
}
}
public List<Entity> GetEntities(List<string> entityNames, ComponentBase component)
public List<Entity> GetEntities(List<string> entityNames, ComponentBase component, List<string> prefabNames = null)
{
List<Entity> entities = new List<Entity>();
foreach (var entityName in entityNames)
@@ -106,6 +106,21 @@ public class EntityManager : SingletonScene<EntityManager>
return entities;
}
public void SetEntity(Entity entity,string prefabName)
{
var prefabData = PrefabManager.Instance.GetPrefab(prefabName);
if (!string.IsNullOrEmpty(prefabName) && prefabData != null)
{
string colorHex = $"#{prefabData.color}";
Debug.Log(colorHex);
if (ColorUtility.TryParseHtmlString(colorHex, out var color))
{
Debug.Log(color);
entity.SetColor(color);
}
}
}
public void DestroyEnity(List<string> entityNames)
{
foreach (var entityName in entityNames)

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 386d5211f9d7bad4ca1de98f8aafd3d0
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
[Serializable]
public class PrefabData
{
public float cost;
public string name;
public List<PrefabDataTag> tags;
public string color;
public string label;
public float width;
public float height;
public float length;
public float weight;
public int priority_order;
}
[Serializable]
public class PrefabDataTag
{
public string key;
public string type;
public string value;
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 742823e6e73bb77419d18af3c3b62cea

View File

@@ -0,0 +1,34 @@
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UVC.Core;
public class PrefabManager : SingletonScene<PrefabManager>
{
public Dictionary<string,PrefabData> prefabDict=new Dictionary<string, PrefabData>();
// Start is called once before the first execution of Update after the MonoBehaviour is created
public void SetPrefabs(List<PrefabData> prefabs)
{
foreach (var prefab in prefabs)
{
if (!prefabDict.ContainsKey(prefab.name))
{
prefabDict.Add(prefab.name, prefab);
}
else
{
prefabDict[prefab.name] = prefab;
}
}
}
public PrefabData GetPrefab(string name)
{
if (string.IsNullOrEmpty(name)||!prefabDict.ContainsKey(name))
{
return null;
}
return prefabDict[name];
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: b2cb1e395c4dad0419182f5c4bf38223

View File

@@ -22,6 +22,6 @@ namespace Simulator.Config
public static int logicId = 258;
public static object logicData = null;
public static string name = "시뮬레이션";
public static SimulatorCreateRequestParameter param = new SimulatorCreateRequestParameter(true, 1, 3600, false);
public static SimulatorCreateRequestParameter param = new SimulatorCreateRequestParameter(true, 10, 3600, false);
}
}

View File

@@ -14,8 +14,8 @@ namespace Simulator
{
onParameterRecived += ComponentsManager.Instance.testRequest;
#if UNITY_EDITOR
SimulationConfig.projectId = 249;
SimulationConfig.logicId = 262;
SimulationConfig.projectId = 278;
SimulationConfig.logicId = 292;
onParameterRecived?.Invoke();
#else
Application.ExternalCall("loadingComplete");