Merge branch 'OctopusSimulator/LH/ConveyorStation' into OctopusSimulator/LH/1104Merge

This commit is contained in:
2025-11-04 19:17:06 +09:00
15 changed files with 582 additions and 85 deletions

View File

@@ -0,0 +1,208 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &1743546011461214031
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1001957461790770069}
m_Layer: 0
m_Name: "\uBD84\uAE30\uBAA8\uB4C8L"
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1001957461790770069
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1743546011461214031}
serializedVersion: 2
m_LocalRotation: {x: -0.7071068, y: -0, z: -0, w: 0.7071068}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 2052993145979945362}
- {fileID: 7496536923071993499}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &3756381672748266326
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2052993145979945362}
- component: {fileID: 2784406749261941934}
- component: {fileID: 7956202039474563351}
m_Layer: 0
m_Name: "\uBD84\uAE30\uBAA8\uB4C8\uB2E4\uB9ACL"
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &2052993145979945362
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3756381672748266326}
serializedVersion: 2
m_LocalRotation: {x: 0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0.00000011920929, y: 0.000000029802322, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1001957461790770069}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!33 &2784406749261941934
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3756381672748266326}
m_Mesh: {fileID: -7295354717946972423, guid: c61fb02733528134c890144f6d31a674, type: 3}
--- !u!23 &7956202039474563351
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3756381672748266326}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RayTracingAccelStructBuildFlagsOverride: 0
m_RayTracingAccelStructBuildFlags: 1
m_SmallMeshCulling: 1
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: -8928447182560981433, guid: c61fb02733528134c890144f6d31a674, type: 3}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!1 &7180079142937912086
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 7496536923071993499}
- component: {fileID: 4373189859820727378}
- component: {fileID: 4700052792092953902}
m_Layer: 0
m_Name: "\uBD84\uAE30\uBAA8\uB4C8\uBAB8\uD1B5L"
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &7496536923071993499
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7180079142937912086}
serializedVersion: 2
m_LocalRotation: {x: 0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: -0, y: 0, z: 0.68220997}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1001957461790770069}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!33 &4373189859820727378
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7180079142937912086}
m_Mesh: {fileID: -5165015696094741570, guid: c61fb02733528134c890144f6d31a674, type: 3}
--- !u!23 &4700052792092953902
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7180079142937912086}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RayTracingAccelStructBuildFlagsOverride: 0
m_RayTracingAccelStructBuildFlags: 1
m_SmallMeshCulling: 1
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: -8928447182560981433, guid: c61fb02733528134c890144f6d31a674, type: 3}
- {fileID: 5995948931272238059, guid: c61fb02733528134c890144f6d31a674, type: 3}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 4e34e1ddae0a5094580500ca1eb5a8d5
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,208 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &743393084340839905
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 8767614793266279683}
m_Layer: 0
m_Name: "\uBD84\uAE30\uBAA8\uB4C8R"
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &8767614793266279683
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 743393084340839905}
serializedVersion: 2
m_LocalRotation: {x: -0.000000115202326, y: 0.7071068, z: 0.7071068, w: 0.000000115202326}
m_LocalPosition: {x: -0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 2049425923868198948}
- {fileID: 2293231737146218039}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &2367961492057466761
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2293231737146218039}
- component: {fileID: 3303958301327171916}
- component: {fileID: 6992582114635376474}
m_Layer: 0
m_Name: "\uBD84\uAE30\uBAA8\uB4C8\uBAB8\uD1B5R"
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &2293231737146218039
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2367961492057466761}
serializedVersion: 2
m_LocalRotation: {x: 0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: -0, y: 0, z: 0.68220997}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 8767614793266279683}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!33 &3303958301327171916
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2367961492057466761}
m_Mesh: {fileID: 1243909848899618088, guid: c61fb02733528134c890144f6d31a674, type: 3}
--- !u!23 &6992582114635376474
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2367961492057466761}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RayTracingAccelStructBuildFlagsOverride: 0
m_RayTracingAccelStructBuildFlags: 1
m_SmallMeshCulling: 1
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: -8928447182560981433, guid: c61fb02733528134c890144f6d31a674, type: 3}
- {fileID: 5995948931272238059, guid: c61fb02733528134c890144f6d31a674, type: 3}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!1 &2471333332602546199
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2049425923868198948}
- component: {fileID: 294626110138049447}
- component: {fileID: 5188180920304978691}
m_Layer: 0
m_Name: "\uBD84\uAE30\uBAA8\uB4C8\uB2E4\uB9ACR"
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &2049425923868198948
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2471333332602546199}
serializedVersion: 2
m_LocalRotation: {x: 0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0.000000119209275, y: 0.000000029802322, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 8767614793266279683}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!33 &294626110138049447
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2471333332602546199}
m_Mesh: {fileID: -5278777494957058985, guid: c61fb02733528134c890144f6d31a674, type: 3}
--- !u!23 &5188180920304978691
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2471333332602546199}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RayTracingAccelStructBuildFlagsOverride: 0
m_RayTracingAccelStructBuildFlags: 1
m_SmallMeshCulling: 1
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: -8928447182560981433, guid: c61fb02733528134c890144f6d31a674, type: 3}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 6fad380c79a6f2f4cb564ec063ade366
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -86,7 +86,7 @@ MonoBehaviour:
evenOnly: 0
trimStart: 0.3
trimEnd: 0.3
spacing: 0
spacing: 0.00001
deforming:
curveOffset: {x: 0, y: 0}
pivotOffset: {x: 0, y: -0.05}

View File

@@ -4434,7 +4434,10 @@ MonoBehaviour:
rootParent: {fileID: 0}
tangentScale: 0.25
splineprefab: {fileID: 8938780329838794364, guid: 69c849c1a1e50764d9bfe6bb460c7b21, type: 3}
cube: {fileID: 919132149155446097, guid: c61fb02733528134c890144f6d31a674, type: 3}
junction: {fileID: 919132149155446097, guid: c61fb02733528134c890144f6d31a674, type: 3}
corner45Prefab: {fileID: 743393084340839905, guid: 6fad380c79a6f2f4cb564ec063ade366, type: 3}
corner90Prefab: {fileID: 743393084340839905, guid: 6fad380c79a6f2f4cb564ec063ade366, type: 3}
angleTolerance: 10
--- !u!4 &1138483813
Transform:
m_ObjectHideFlags: 0

View File

@@ -34,6 +34,7 @@ namespace Simulator.Data.Transport
var duration = timing.GetDataObject("duration");
targetPosition = AGVNodeManager.Instance.GetNodePosition(datas.GetString("to_node"));
startPosition = AGVNodeManager.Instance.GetNodePosition(datas.GetString("from_node"));
Debug.Log($"{agvData.GetDateTime("timestamp")}from{datas.GetString("from_node")}/to{datas.GetString("to_node")}");
moveSpeed = (float)duration.GetFloat("real_seconds");
t = 0f;
getdata = true;
@@ -56,8 +57,6 @@ namespace Simulator.Data.Transport
// 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;
// 중복 방지 후 등록

View File

@@ -53,12 +53,12 @@ public class StackerCrane : ComponentBase
var fy = (int)from.GetInt("y");
var fz = (int)from.GetInt("z");
horizontalStart = new Vector3(horizonObject.transform.position.x, 0, startposition.z);
verticalStart = new Vector3(-0.03920534f, -0.2531985f, verticalObject.transform.position.z);
verticalStart = new Vector3(-0.03920534f, -0.2531985f, verticalObject.transform.localPosition.z);
var to = crane_movement.GetDataObject("to_position");
var tx = (int)to.GetInt("x");
var ty = (int)to.GetInt("y");
var tz = (int)to.GetInt("z");
var rackp = rack.cellComponents[(tx, tz, ty)].transform.position;
var rackp = rack.cellComponents[(tx, ty, tz)].transform.position;
//Debug.Log($"{tx},{ty},{tz}");
horizontalTarget = new Vector3(rackp.x, 0, startposition.z);
verticalTarget = new Vector3(-0.03920534f, -0.2531985f, rackp.y);
@@ -88,7 +88,7 @@ public class StackerCrane : ComponentBase
var x = (int)position.GetInt("x");
var y = (int)position.GetInt("y");
var z = (int)position.GetInt("z");
var rackp = rack.cellComponents[(x, z, y)].transform.position;
var rackp = rack.cellComponents[(x, y, z)].transform.position;
ft = 0f;
forkTarget = new Vector3(-rackp.z+startposition.x,0, 0.3f);
Debug.Log($"t{forkTarget}");

View File

@@ -3,4 +3,7 @@ using UnityEngine;
public class CellComponent : MonoBehaviour
{
public GameObject Socket;
public int x;
public int y;
public int z;
}

View File

@@ -170,21 +170,21 @@ namespace Simulator.Data
private async void testRequest()
{
var data = await HttpRequester.RequestGet<Totaljson>($"{Constants.HTTP_DOMAIN}/simulation/logics/35", null, null, true);
var data = await HttpRequester.RequestGet<Totaljson>($"{Constants.HTTP_DOMAIN}/simulation/logics/61", null, null, true);
logicDetailData = data.data.data;
SimulatorCreateRequestParameter param = new SimulatorCreateRequestParameter();
param.speed = SimulationConfig.speed;
Dictionary<string, object> body = new Dictionary<string, object>()
{
{ "projectId",18 },
{ "logicId",35 },
{ "logicId",61 },
{ "logicData",null },
{ "name","새 시뮬레이션2" },
{ "parameters",param }
};
var cdata = await HttpRequester.RequestPost<SimulatorCodeDataClass>($"{Constants.HTTP_DOMAIN}/simulation/histories", body, null, true);
codedata = cdata;
SimulationConfig.SimulationCode = codedata.data.data.simulationCode;
//var cdata = await HttpRequester.RequestPost<SimulatorCodeDataClass>($"{Constants.HTTP_DOMAIN}/simulation/histories", body, null, true);
//codedata = cdata;
//SimulationConfig.SimulationCode = codedata.data.data.simulationCode;
if (data.data.data.production_system.conveyors != null && data.data.data.production_system.conveyors.Count >= 1)
{
ConveyorManager.Instance.Build(data.data.data.production_system.conveyors);
@@ -204,9 +204,9 @@ namespace Simulator.Data
}
}
}
SpawnComponents(data.data.data);
SubscribeTopic();
DataRepository.Instance.MqttReceiver.Start();
//SpawnComponents(data.data.data);
//SubscribeTopic();
//DataRepository.Instance.MqttReceiver.Start();
}
void SubscribeTopic()
@@ -246,7 +246,6 @@ namespace Simulator.Data
{
SinkComponent? sink = sinkPool.GetItem(obj.GetString("component_id")!);
sink.GetModelData(obj);
Debug.Log(obj);
}
break;
case ComponentType.Queue:

View File

@@ -4,6 +4,7 @@ using Simulator.Data.Transport;
using System;
using System.Collections.Generic;
using System.Linq;
using Unity.Collections;
using UnityEngine;
using UnityEngine.Splines;
using UVC.Core;
@@ -25,21 +26,30 @@ public class ConveyorManager : SingletonScene<ConveyorManager>
[Header("Root & Visual")]
[SerializeField] private Transform rootParent; // 생성될 경로의 부모(없으면 빌더 자신)
[SerializeField] private float tangentScale = 0.25f; // 곡률(탄젠트 길이 비율)
[SerializeField]
ConveyorComponent splineprefab;
[SerializeField]
GameObject cube;
[SerializeField] private ConveyorComponent splineprefab;
[SerializeField] private GameObject junction;
[Header("Corner Modules")] // ▼ 추가: 코너 프리팹 & 각도 허용 오차
[SerializeField] private GameObject corner45Prefab;
[SerializeField] private GameObject corner90Prefab;
[SerializeField, Range(1f, 30f)] private float angleTolerance = 10f;
public Dictionary<string, ConveyorNode> Nodes = new Dictionary<string, ConveyorNode>();
public Dictionary<(string,string), ConveyorComponent> Paths = new Dictionary<(string, string), ConveyorComponent>();
public Dictionary<(string, string), ConveyorComponent> Paths = new Dictionary<(string, string), ConveyorComponent>();
// ▼ 추가: station 연결성 계산용 테이블
// stationName -> (경로 키, station에서 맞닿는 cap index(0=from,1=to), 반대편 노드명)
private readonly Dictionary<string, List<(ValueTuple<string, string> pathKey, int capIndex, string otherNode)>> _stationAdj
= new Dictionary<string, List<(ValueTuple<string, string>, int, string)>>();
public DataMapper conveyorStartDataMapper;
public DataMapper conveyorCompleteDataMapper;
protected override void Init()
{
var conveyorStartDataMask = new DataMask();
conveyorStartDataMask.ObjectName = "conveyor"; // AGV 객체의 이름을 설정합니다.
conveyorStartDataMask.ObjectIdKey = "component_id"; // AGV의 고유 식별자로 사용할 키를 설정합니다.
conveyorStartDataMask.ObjectName = "conveyor";
conveyorStartDataMask.ObjectIdKey = "component_id";
conveyorStartDataMask["component_id"] = "";
conveyorStartDataMask["event_name"] = "";
conveyorStartDataMask["timestamp"] = new DateTime();
@@ -48,13 +58,13 @@ public class ConveyorManager : SingletonScene<ConveyorManager>
["entity_id_original"] = "",
["start_node"] = "",
["end_node"] = "",
["travel_time"]=0.0f
["travel_time"] = 0.0f
};
conveyorStartDataMapper=new DataMapper(conveyorStartDataMask);
conveyorStartDataMapper = new DataMapper(conveyorStartDataMask);
var conveyorCompleteDataMask = new DataMask();
conveyorCompleteDataMask.ObjectName = "conveyor"; // AGV 객체의 이름을 설정합니다.
conveyorCompleteDataMask.ObjectIdKey = "component_id"; // AGV의 고유 식별자로 사용할 키를 설정합니다.
conveyorCompleteDataMask.ObjectName = "conveyor";
conveyorCompleteDataMask.ObjectIdKey = "component_id";
conveyorCompleteDataMask["component_id"] = "";
conveyorCompleteDataMask["event_name"] = "";
conveyorCompleteDataMask["timestamp"] = new DateTime();
@@ -69,27 +79,29 @@ public class ConveyorManager : SingletonScene<ConveyorManager>
public void Build(List<ConveyorDataClass> datas)
{
if (datas==null||datas.Count <= 0)
{
return;
}
if (datas == null || datas.Count <= 0) return;
var data = datas[0];
if (rootParent == null) rootParent = transform;
Nodes.Clear();
Paths.Clear();
_stationAdj.Clear(); // ▲ 추가: 초기화
if (data.nodes != null)
{
foreach (var n in data.nodes)
{
Nodes[n.name] = n;
}
}
foreach (var path in data.paths)
{
CreatePathGOWithSpline(path, Nodes[path.from_node], Nodes[path.to_node]);
}
SpawnJunction();
// ▲ 추가: station의 연결성(직선/코너) 기반 cap 분리 & 코너 배치
ProcessStations();
SubscribeConveyor(data);
}
@@ -100,27 +112,18 @@ public class ConveyorManager : SingletonScene<ConveyorManager>
mqttConfigConveyorStart.SetDataMapper(conveyorStartDataMapper);
mqttConfigConveyorStart.SetHandler(OnSetData);
DataRepository.Instance.MqttReceiver.Add(mqttConfigConveyorStart);
/*
DataRepository.Instance.MqttReceiver.AddTopic($"simulation/{SimulationConfig.SimulationCode}/components/+/{data.name}/+/node_completed");
var mqttConfigConveyorComplete = new MqttSubscriptionConfig($"simulation/{SimulationConfig.SimulationCode}/components/+/{data.name}/+/node_completed");
mqttConfigConveyorComplete.SetDataMapper(conveyorCompleteDataMapper);
mqttConfigConveyorComplete.SetHandler(OnUnSetData);
DataRepository.Instance.MqttReceiver.Add(mqttConfigConveyorComplete);
*/
}
private void CreatePathGOWithSpline(ConveyorPath path, ConveyorNode fromNode, ConveyorNode toNode)
{
TryGetNodePos(fromNode.name, out Vector3 fromPos);
TryGetNodePos(toNode.name, out Vector3 toPos);
string goName = path.name;
var go = Instantiate(splineprefab);
Paths.Add((fromNode.name,toNode.name), go);
Paths.Add((fromNode.name, toNode.name), go);
go.transform.SetParent(rootParent, worldPositionStays: false);
var container = go.GetComponent<SplineContainer>();
var spline = new Spline();
Vector3 dir = (toPos - fromPos);
@@ -146,26 +149,100 @@ public class ConveyorManager : SingletonScene<ConveyorManager>
container.Spline = spline;
var mesher = go.GetComponent<SplineMesher>();
if(string.Equals(fromNode.node_type, "junction"))
{
// ▼ 변경: junction만 즉시 cap 분리, station은 후처리에서 판단
if (string.Equals(fromNode.node_type, "junction"))
mesher.DetachCap(0);
}
if (string.Equals(toNode.node_type, "junction"))
{
mesher.DetachCap(1);
mesher.UpdateCaps();
mesher.Rebuild();
// ▼ 추가: station 인접 정보 기록(후처리에서 cap/코너 결정)
if (string.Equals(fromNode.node_type, "station"))
AddStationAdj(fromNode.name, (fromNode.name, toNode.name), capIndex: 0, otherNode: toNode.name);
if (string.Equals(toNode.node_type, "station"))
AddStationAdj(toNode.name, (fromNode.name, toNode.name), capIndex: 1, otherNode: fromNode.name);
}
// ▼ 추가: station 인접 정보 수집
private void AddStationAdj(string stationName, (string, string) pathKey, int capIndex, string otherNode)
{
if (!_stationAdj.TryGetValue(stationName, out var list))
{
list = new List<(ValueTuple<string, string>, int, string)>();
_stationAdj[stationName] = list;
}
list.Add((pathKey, capIndex, otherNode));
}
// ▼ 추가: station의 연결성이 직선인지 코너인지 판정하고 cap/코너를 적용
private void ProcessStations()
{
foreach (var kv in _stationAdj)
{
string station = kv.Key;
var adj = kv.Value;
// 연결 경로가 2개일 때만 직선/코너 판정(기타 케이스는 유지)
if (adj.Count != 2) continue;
if (!TryGetNodePos(station, out var stationPos)) continue;
var (pathA, capA, otherA) = adj[0];
var (pathB, capB, otherB) = adj[1];
if (!TryGetNodePos(otherA, out var otherAPos)) continue;
if (!TryGetNodePos(otherB, out var otherBPos)) continue;
Vector3 vA = (otherAPos - stationPos); vA.y = 0f;
Vector3 vB = (otherBPos - stationPos); vB.y = 0f;
if (vA.sqrMagnitude < 1e-6f || vB.sqrMagnitude < 1e-6f) continue;
float angle = Vector3.SignedAngle(vA.normalized, vB.normalized, Vector3.up); // 0~180
float straightThreshold = 180f - angleTolerance; // 예: tol=10 → 170°
Debug.Log(angle);
bool isStraight = Mathf.Abs(angle) >= straightThreshold; // 거의 반대 방향이면 직선
if (isStraight)
{
// 직선: cap 유지
continue;
}
// 코너: station에 맞닿는 두 cap 분리
if (Paths.TryGetValue(pathA, out var convA))
DetachAndRebuild(convA, capA);
if (Paths.TryGetValue(pathB, out var convB))
DetachAndRebuild(convB, capB);
var corner = Instantiate(corner90Prefab);
corner.transform.position = stationPos;
corner.transform.rotation = Quaternion.Euler(new Vector3(-90, -angle, 0));
}
}
// ▼ 추가: cap 분리 & 리빌드 헬퍼
private void DetachAndRebuild(ConveyorComponent comp, int capIndex)
{
var mesher = comp.GetComponent<SplineMesher>();
if (mesher == null) return;
mesher.DetachCap(capIndex);
mesher.UpdateCaps();
mesher.Rebuild();
}
private void SpawnJunction()
{
foreach(var node in Nodes)
foreach (var node in Nodes)
{
if (string.Equals(node.Value.node_type, "junction"))
{
var module = Instantiate(cube);
module.transform.position=ToVector3(node.Value.position);
var module = Instantiate(junction);
module.transform.position = ToVector3(node.Value.physical.position);
}
}
}
@@ -176,33 +253,19 @@ public class ConveyorManager : SingletonScene<ConveyorManager>
DataObject? obj = idata as DataObject;
if (obj == null) return;
//Debug.Log($"OnUpdateData:{obj}, {obj["data"]}");
var data = obj.GetDataObject("data");
var fromNodeName = data.GetString("start_node");
var toNodeName = data.GetString("end_node");
ConveyorComponent? conveyor = Paths[(fromNodeName,toNodeName)];
conveyor.SetModelData(obj);
}
private void OnUnSetData(IDataObject idata)
{
if (idata == null) return;
DataObject? obj = idata as DataObject;
if (obj == null) return;
//Debug.Log($"OnUpdateData:{obj}, {obj["data"]}");
var data = obj.GetDataObject("data");
var fromNodeName = data.GetString("start_node");
var toNodeName = data.GetString("end_node");
ConveyorComponent? conveyor = Paths[(fromNodeName, toNodeName)];
conveyor.UnSetModelData(obj);
conveyor.SetModelData(obj);
}
private bool TryGetNodePos(string nodeName, out Vector3 pos)
{
if (!string.IsNullOrWhiteSpace(nodeName) && Nodes.TryGetValue(nodeName, out ConveyorNode node))
{
pos = ToVector3(node.position);
pos = ToVector3(node.physical.position);
return true;
}
@@ -212,6 +275,7 @@ public class ConveyorManager : SingletonScene<ConveyorManager>
private Vector3 ToVector3(Position p)
{
Debug.Log(p);
return new Vector3(p.x, p.z, p.y);
}
}

View File

@@ -17,7 +17,7 @@ namespace Simulator.Data
{
public string name;
public int capacity;
public Position position;
public Physical physical;
public string node_type;
}

View File

@@ -1,6 +1,4 @@
using Simulator.Model;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UVC.Data.Core;
@@ -30,14 +28,14 @@ namespace Simulator.Data {
var y = (int)coordinates.GetInt("y");
var z = (int)coordinates.GetInt("z");
var entity=EntityManager.Instance.GetEntities(entityids,this);
entity[0].transform.SetParent(cellComponents[(x, z, y)].Socket.transform);
entity[0].transform.SetParent(cellComponents[(x, y, z)].Socket.transform);
entity[0].transform.localPosition = new Vector3(0, 0, 0);
entitys.Add(entity[0].gameObject);
}
public void SpawnCell(rack_layout layout,bool asrs)
{
Vector3 center = new Vector3(layout.x * layout.x_length / 2f, 0f, layout.y * layout.y_length / 2f);
Vector3 center = new Vector3(layout.x * layout.x_length / 2f, 0f, layout.z * layout.z_length / 2f);
transform.position = center;
for (int z = 0; z < layout.z; z++)
@@ -47,25 +45,28 @@ namespace Simulator.Data {
for(int x=0;x<layout.x; x++)
{
var cell = Instantiate(cellPrefab);
cell.transform.localScale=new Vector3(layout.x_length, layout.z_length, layout.y_length);
cell.transform.localScale=new Vector3(layout.x_length, layout.y_length, layout.z_length);
cell.transform.position = new Vector3(layout.x_length * x*0.55f, layout.y_length * y * 0.59f, layout.z_length * z * 0.75f);
cell.transform.parent = this.transform;
cell.transform.position = new Vector3(layout.x_length * x*0.55f, layout.z_length * z * 0.55f, layout.y_length * y * 0.55f);
cellComponents.Add((x, z, y), cell.GetComponent<CellComponent>());
cellComponents.Add((x, y, z), cell.GetComponent<CellComponent>());
cellComponents[(x, y, z)].x = x;
cellComponents[(x, y, z)].y = y;
cellComponents[(x, y, z)].z = z;
}
}
}
if (asrs)
{
var pickcell = Instantiate(cellPrefab);
pickcell.transform.localScale = new Vector3(layout.x_length, layout.z_length, layout.y_length);
pickcell.transform.localScale = new Vector3(layout.x_length, layout.y_length, layout.z_length);
pickcell.transform.position = new Vector3(layout.x_length * -0.55f, layout.y_length * 0, layout.z_length * 0);
pickcell.transform.parent = this.transform;
pickcell.transform.position = new Vector3(layout.x_length * -0.55f, layout.z_length * 0, layout.y_length * 0);
cellComponents.Add((-1, 0, 0), pickcell.GetComponent<CellComponent>());
var dropcell = Instantiate(cellPrefab);
dropcell.transform.localScale = new Vector3(layout.x_length, layout.z_length, layout.y_length);
dropcell.transform.localScale = new Vector3(layout.x_length, layout.y_length, layout.z_length);
dropcell.transform.position = new Vector3(layout.x_length * (layout.x)*0.55f, layout.y_length * 0, layout.z_length * 0);
dropcell.transform.parent = this.transform;
dropcell.transform.position = new Vector3(layout.x_length * (layout.x+ 0.55f), layout.z_length * 0, layout.y_length * 0);
cellComponents.Add(((int)(layout.x + 1), 0, 0), dropcell.GetComponent<CellComponent>());
cellComponents.Add(((int)(layout.x), 0, 0), dropcell.GetComponent<CellComponent>());
}
}
}

View File

@@ -100,9 +100,7 @@ public class EntityManager : SingletonScene<EntityManager>
List<Entity> entities = new List<Entity>();
foreach (var entityName in entityNames)
{
var entity = entityDatas[entityName];
possessComponents[entity].DecreaseEntity(entity);
possessComponents[entity] = component;
var entity = GetEntity(entityName, component);
entities.Add(entity);
}
return entities;

View File

@@ -14,6 +14,6 @@ public static class SimulationConfig
onSimulationCodeSet?.Invoke(simulationCode);
}
}
public static int speed = 10;
public static int speed = 3;
public static int duration = 3600;
}