diff --git a/Assets/Resources/Prefabs/SampleProject/Factory/AGV.prefab b/Assets/Resources/Prefabs/SampleProject/Factory/AGV.prefab
index 5e341c0a..d9ee14cc 100644
--- a/Assets/Resources/Prefabs/SampleProject/Factory/AGV.prefab
+++ b/Assets/Resources/Prefabs/SampleProject/Factory/AGV.prefab
@@ -10,9 +10,6 @@ GameObject:
m_Component:
- component: {fileID: 302300799186228596}
- component: {fileID: 8488195170614820883}
- - component: {fileID: 3820258601269832329}
- - component: {fileID: 363746616583149630}
- - component: {fileID: 5360656424770899642}
m_Layer: 0
m_Name: AGV
m_TagString: Untagged
@@ -32,7 +29,8 @@ Transform:
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
- m_Children: []
+ m_Children:
+ - {fileID: 8708419218786706813}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &8488195170614820883
@@ -47,24 +45,72 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: bc083cb3e97c87446bc1a7db7b4ef9e4, type: 3}
m_Name:
m_EditorClassIdentifier:
- moveSpeed: 1
- rotationSpeed: 1
+ modelObject: {fileID: 7493524444357289953}
+ moveSpeed: 0.5
+ rotationSpeed: 0.5
teleportDistanceThreshold: 5
---- !u!33 &3820258601269832329
+--- !u!1 &6358428858938227828
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 8708419218786706813}
+ - component: {fileID: 7493524444357289953}
+ - component: {fileID: 6887510220552103127}
+ - component: {fileID: 9132754914965147154}
+ - component: {fileID: 6486094733119401088}
+ m_Layer: 0
+ m_Name: Cube
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &8708419218786706813
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 6358428858938227828}
+ serializedVersion: 2
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 0, y: 0.5, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 302300799186228596}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &7493524444357289953
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 6358428858938227828}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 369f10656ae555b4983fa3147fc56818, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+--- !u!33 &6887510220552103127
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
- m_GameObject: {fileID: 1373625414374435398}
+ m_GameObject: {fileID: 6358428858938227828}
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
---- !u!23 &363746616583149630
+--- !u!23 &9132754914965147154
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
- m_GameObject: {fileID: 1373625414374435398}
+ m_GameObject: {fileID: 6358428858938227828}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
@@ -103,13 +149,13 @@ MeshRenderer:
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
---- !u!65 &5360656424770899642
+--- !u!65 &6486094733119401088
BoxCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
- m_GameObject: {fileID: 1373625414374435398}
+ m_GameObject: {fileID: 6358428858938227828}
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
@@ -118,7 +164,7 @@ BoxCollider:
serializedVersion: 2
m_Bits: 0
m_LayerOverridePriority: 0
- m_IsTrigger: 1
+ m_IsTrigger: 0
m_ProvidesContacts: 0
m_Enabled: 1
serializedVersion: 3
diff --git a/Assets/Resources/Prefabs/SampleProject/Factory/Alarm.prefab b/Assets/Resources/Prefabs/SampleProject/Factory/Alarm.prefab
new file mode 100644
index 00000000..88ac3a83
--- /dev/null
+++ b/Assets/Resources/Prefabs/SampleProject/Factory/Alarm.prefab
@@ -0,0 +1,415 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1 &494093931030574861
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 5765213305061083199}
+ - component: {fileID: 4826901156942800586}
+ - component: {fileID: 8650239058674280921}
+ m_Layer: 5
+ m_Name: Text (TMP)
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &5765213305061083199
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 494093931030574861}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 2463437008278947656}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_AnchorMin: {x: 0, y: 0}
+ m_AnchorMax: {x: 1, y: 1}
+ m_AnchoredPosition: {x: 0, y: 0}
+ m_SizeDelta: {x: 0, y: 0}
+ m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &4826901156942800586
+CanvasRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 494093931030574861}
+ m_CullTransparentMesh: 1
+--- !u!114 &8650239058674280921
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 494093931030574861}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_Material: {fileID: 0}
+ m_Color: {r: 1, g: 1, b: 1, a: 1}
+ m_RaycastTarget: 1
+ m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+ m_Maskable: 1
+ m_OnCullStateChanged:
+ m_PersistentCalls:
+ m_Calls: []
+ m_text: 0
+ m_isRightToLeft: 0
+ m_fontAsset: {fileID: 11400000, guid: 08cebd004d97ca742ac80400f37f4eed, type: 2}
+ m_sharedMaterial: {fileID: 4860575619018115804, guid: 08cebd004d97ca742ac80400f37f4eed, type: 2}
+ m_fontSharedMaterials: []
+ m_fontMaterial: {fileID: 0}
+ m_fontMaterials: []
+ m_fontColor32:
+ serializedVersion: 2
+ rgba: 4278190080
+ m_fontColor: {r: 0, g: 0, b: 0, a: 1}
+ m_enableVertexGradient: 0
+ m_colorMode: 3
+ m_fontColorGradient:
+ topLeft: {r: 1, g: 1, b: 1, a: 1}
+ topRight: {r: 1, g: 1, b: 1, a: 1}
+ bottomLeft: {r: 1, g: 1, b: 1, a: 1}
+ bottomRight: {r: 1, g: 1, b: 1, a: 1}
+ m_fontColorGradientPreset: {fileID: 0}
+ m_spriteAsset: {fileID: 0}
+ m_tintAllSprites: 0
+ m_StyleSheet: {fileID: 0}
+ m_TextStyleHashCode: -1183493901
+ m_overrideHtmlColors: 0
+ m_faceColor:
+ serializedVersion: 2
+ rgba: 4294967295
+ m_fontSize: 36
+ m_fontSizeBase: 36
+ m_fontWeight: 400
+ m_enableAutoSizing: 0
+ m_fontSizeMin: 18
+ m_fontSizeMax: 72
+ m_fontStyle: 0
+ m_HorizontalAlignment: 2
+ m_VerticalAlignment: 512
+ m_textAlignment: 65535
+ m_characterSpacing: 0
+ m_wordSpacing: 0
+ m_lineSpacing: 0
+ m_lineSpacingMax: 0
+ m_paragraphSpacing: 0
+ m_charWidthMaxAdj: 0
+ m_TextWrappingMode: 1
+ m_wordWrappingRatios: 0.4
+ m_overflowMode: 0
+ m_linkedTextComponent: {fileID: 0}
+ parentLinkedComponent: {fileID: 0}
+ m_enableKerning: 0
+ m_ActiveFontFeatures: 6e72656b
+ m_enableExtraPadding: 0
+ checkPaddingRequired: 0
+ m_isRichText: 1
+ m_EmojiFallbackSupport: 1
+ m_parseCtrlCharacters: 1
+ m_isOrthographic: 1
+ m_isCullingEnabled: 0
+ m_horizontalMapping: 0
+ m_verticalMapping: 0
+ m_uvLineOffset: 0
+ m_geometrySortingOrder: 0
+ m_IsTextObjectScaleStatic: 0
+ m_VertexBufferAutoSizeReduction: 0
+ m_useMaxVisibleDescender: 1
+ m_pageToDisplay: 1
+ m_margin: {x: 0, y: 0, z: 0, w: 0}
+ m_isUsingLegacyAnimationComponent: 0
+ m_isVolumetricText: 0
+ m_hasFontAssetChanged: 0
+ m_baseMaterial: {fileID: 0}
+ m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
+--- !u!1 &952545100964675415
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 8574585598928791195}
+ m_Layer: 5
+ m_Name: expandedView
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &8574585598928791195
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 952545100964675415}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 2463437008278947656}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_AnchorMin: {x: 0, y: 0}
+ m_AnchorMax: {x: 1, y: 1}
+ m_AnchoredPosition: {x: 0, y: 0}
+ m_SizeDelta: {x: 0, y: 0}
+ m_Pivot: {x: 0.5, y: 0.5}
+--- !u!1 &1828762385695490929
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 2463437008278947656}
+ - component: {fileID: 5380681345511526047}
+ m_Layer: 5
+ m_Name: Alarm
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &2463437008278947656
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1828762385695490929}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children:
+ - {fileID: 5007029136827874888}
+ - {fileID: 5765213305061083199}
+ - {fileID: 8574585598928791195}
+ m_Father: {fileID: 0}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_AnchorMin: {x: 0.5, y: 0.5}
+ m_AnchorMax: {x: 0.5, y: 0.5}
+ m_AnchoredPosition: {x: 0, y: 0}
+ m_SizeDelta: {x: 100, y: 100}
+ m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &5380681345511526047
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1828762385695490929}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 773fa02b59601044b8be752f78f63e55, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ clusterView: {fileID: 4918696741701580718}
+ alarmCountText: {fileID: 8650239058674280921}
+ expandedView: {fileID: 952545100964675415}
+ singleAlarmIconPrefab: {fileID: 7314511769243682470, guid: e9acc8c9a93a2b5409fc01661660b217, type: 3}
+--- !u!1 &4918696741701580718
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 5007029136827874888}
+ m_Layer: 5
+ m_Name: clusterView
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &5007029136827874888
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 4918696741701580718}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children:
+ - {fileID: 7229327262419467602}
+ - {fileID: 1591538567731418999}
+ m_Father: {fileID: 2463437008278947656}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_AnchorMin: {x: 0, y: 0}
+ m_AnchorMax: {x: 1, y: 1}
+ m_AnchoredPosition: {x: 0, y: 0}
+ m_SizeDelta: {x: 0, y: 0}
+ m_Pivot: {x: 0.5, y: 0.5}
+--- !u!1 &7297564150823027611
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 7229327262419467602}
+ - component: {fileID: 7287393582081843390}
+ - component: {fileID: 4544043674251718843}
+ m_Layer: 5
+ m_Name: shadow
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &7229327262419467602
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 7297564150823027611}
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 5007029136827874888}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_AnchorMin: {x: 0, y: 0}
+ m_AnchorMax: {x: 1, y: 1}
+ m_AnchoredPosition: {x: 5, y: -5}
+ m_SizeDelta: {x: 10, y: 10}
+ m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &7287393582081843390
+CanvasRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 7297564150823027611}
+ m_CullTransparentMesh: 1
+--- !u!114 &4544043674251718843
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 7297564150823027611}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_Material: {fileID: 0}
+ m_Color: {r: 0, g: 0, b: 0, a: 1}
+ m_RaycastTarget: 1
+ m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+ m_Maskable: 1
+ m_OnCullStateChanged:
+ m_PersistentCalls:
+ m_Calls: []
+ m_Sprite: {fileID: 887145076, guid: 4cf3568ca3f55f64cb11447d139d7a3d, type: 3}
+ m_Type: 1
+ m_PreserveAspect: 0
+ m_FillCenter: 1
+ m_FillMethod: 4
+ m_FillAmount: 1
+ m_FillClockwise: 1
+ m_FillOrigin: 0
+ m_UseSpriteMesh: 0
+ m_PixelsPerUnitMultiplier: 1
+--- !u!1 &7656214594090597472
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1591538567731418999}
+ - component: {fileID: 8641121927952400765}
+ - component: {fileID: 4970931623191621822}
+ m_Layer: 5
+ m_Name: bg
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &1591538567731418999
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 7656214594090597472}
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 5007029136827874888}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_AnchorMin: {x: 0, y: 0}
+ m_AnchorMax: {x: 1, y: 1}
+ m_AnchoredPosition: {x: 0, y: 0}
+ m_SizeDelta: {x: 0, y: 0}
+ m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &8641121927952400765
+CanvasRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 7656214594090597472}
+ m_CullTransparentMesh: 1
+--- !u!114 &4970931623191621822
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 7656214594090597472}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_Material: {fileID: 0}
+ m_Color: {r: 1, g: 1, b: 1, a: 1}
+ m_RaycastTarget: 1
+ m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+ m_Maskable: 1
+ m_OnCullStateChanged:
+ m_PersistentCalls:
+ m_Calls: []
+ m_Sprite: {fileID: -895992892, guid: 73d757b5d1b754245969af12daf01e78, type: 3}
+ m_Type: 1
+ m_PreserveAspect: 0
+ m_FillCenter: 1
+ m_FillMethod: 4
+ m_FillAmount: 1
+ m_FillClockwise: 1
+ m_FillOrigin: 0
+ m_UseSpriteMesh: 0
+ m_PixelsPerUnitMultiplier: 1
diff --git a/Assets/Resources/Prefabs/SampleProject/Factory/Alarm.prefab.meta b/Assets/Resources/Prefabs/SampleProject/Factory/Alarm.prefab.meta
new file mode 100644
index 00000000..3ecd0bd1
--- /dev/null
+++ b/Assets/Resources/Prefabs/SampleProject/Factory/Alarm.prefab.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: e8b88e69e607ee448806427e91440a8e
+PrefabImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Resources/Prefabs/SampleProject/Factory/AlarmIcon.prefab b/Assets/Resources/Prefabs/SampleProject/Factory/AlarmIcon.prefab
new file mode 100644
index 00000000..d2d29662
--- /dev/null
+++ b/Assets/Resources/Prefabs/SampleProject/Factory/AlarmIcon.prefab
@@ -0,0 +1,340 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1 &1326045257776503954
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 8602533637707951236}
+ - component: {fileID: 5770335694761070239}
+ - component: {fileID: 2018211268787215362}
+ m_Layer: 5
+ m_Name: Text (TMP)
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &8602533637707951236
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1326045257776503954}
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 3374630250525829090}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_AnchorMin: {x: 0, y: 0}
+ m_AnchorMax: {x: 1, y: 1}
+ m_AnchoredPosition: {x: 0, y: 0}
+ m_SizeDelta: {x: -20, y: -20}
+ m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &5770335694761070239
+CanvasRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1326045257776503954}
+ m_CullTransparentMesh: 1
+--- !u!114 &2018211268787215362
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1326045257776503954}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_Material: {fileID: 0}
+ m_Color: {r: 1, g: 1, b: 1, a: 1}
+ m_RaycastTarget: 1
+ m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+ m_Maskable: 1
+ m_OnCullStateChanged:
+ m_PersistentCalls:
+ m_Calls: []
+ m_text: TR
+ m_isRightToLeft: 0
+ m_fontAsset: {fileID: 11400000, guid: 08cebd004d97ca742ac80400f37f4eed, type: 2}
+ m_sharedMaterial: {fileID: 4860575619018115804, guid: 08cebd004d97ca742ac80400f37f4eed, type: 2}
+ m_fontSharedMaterials: []
+ m_fontMaterial: {fileID: 0}
+ m_fontMaterials: []
+ m_fontColor32:
+ serializedVersion: 2
+ rgba: 4278190080
+ m_fontColor: {r: 0, g: 0, b: 0, a: 1}
+ m_enableVertexGradient: 0
+ m_colorMode: 3
+ m_fontColorGradient:
+ topLeft: {r: 1, g: 1, b: 1, a: 1}
+ topRight: {r: 1, g: 1, b: 1, a: 1}
+ bottomLeft: {r: 1, g: 1, b: 1, a: 1}
+ bottomRight: {r: 1, g: 1, b: 1, a: 1}
+ m_fontColorGradientPreset: {fileID: 0}
+ m_spriteAsset: {fileID: 0}
+ m_tintAllSprites: 0
+ m_StyleSheet: {fileID: 0}
+ m_TextStyleHashCode: -1183493901
+ m_overrideHtmlColors: 0
+ m_faceColor:
+ serializedVersion: 2
+ rgba: 4294967295
+ m_fontSize: 12
+ m_fontSizeBase: 12
+ m_fontWeight: 400
+ m_enableAutoSizing: 0
+ m_fontSizeMin: 18
+ m_fontSizeMax: 72
+ m_fontStyle: 0
+ m_HorizontalAlignment: 1
+ m_VerticalAlignment: 256
+ m_textAlignment: 65535
+ m_characterSpacing: 0
+ m_wordSpacing: 0
+ m_lineSpacing: 0
+ m_lineSpacingMax: 0
+ m_paragraphSpacing: 0
+ m_charWidthMaxAdj: 0
+ m_TextWrappingMode: 1
+ m_wordWrappingRatios: 0.4
+ m_overflowMode: 0
+ m_linkedTextComponent: {fileID: 0}
+ parentLinkedComponent: {fileID: 0}
+ m_enableKerning: 0
+ m_ActiveFontFeatures: 6e72656b
+ m_enableExtraPadding: 0
+ checkPaddingRequired: 0
+ m_isRichText: 1
+ m_EmojiFallbackSupport: 1
+ m_parseCtrlCharacters: 1
+ m_isOrthographic: 1
+ m_isCullingEnabled: 0
+ m_horizontalMapping: 0
+ m_verticalMapping: 0
+ m_uvLineOffset: 0
+ m_geometrySortingOrder: 0
+ m_IsTextObjectScaleStatic: 0
+ m_VertexBufferAutoSizeReduction: 0
+ m_useMaxVisibleDescender: 1
+ m_pageToDisplay: 1
+ m_margin: {x: 0, y: 0, z: 0, w: 0}
+ m_isUsingLegacyAnimationComponent: 0
+ m_isVolumetricText: 0
+ m_hasFontAssetChanged: 0
+ m_baseMaterial: {fileID: 0}
+ m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
+--- !u!1 &3798696889335606665
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 6765948511015989509}
+ - component: {fileID: 2825211744860677609}
+ - component: {fileID: 7215137539608397115}
+ m_Layer: 5
+ m_Name: shadow
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &6765948511015989509
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 3798696889335606665}
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 3374630250525829090}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_AnchorMin: {x: 0, y: 0}
+ m_AnchorMax: {x: 1, y: 1}
+ m_AnchoredPosition: {x: 5, y: -5}
+ m_SizeDelta: {x: 10, y: 10}
+ m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &2825211744860677609
+CanvasRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 3798696889335606665}
+ m_CullTransparentMesh: 1
+--- !u!114 &7215137539608397115
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 3798696889335606665}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_Material: {fileID: 0}
+ m_Color: {r: 0, g: 0, b: 0, a: 1}
+ m_RaycastTarget: 1
+ m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+ m_Maskable: 1
+ m_OnCullStateChanged:
+ m_PersistentCalls:
+ m_Calls: []
+ m_Sprite: {fileID: 887145076, guid: 4cf3568ca3f55f64cb11447d139d7a3d, type: 3}
+ m_Type: 1
+ m_PreserveAspect: 0
+ m_FillCenter: 1
+ m_FillMethod: 4
+ m_FillAmount: 1
+ m_FillClockwise: 1
+ m_FillOrigin: 0
+ m_UseSpriteMesh: 0
+ m_PixelsPerUnitMultiplier: 1
+--- !u!1 &7314511769243682470
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 3374630250525829090}
+ - component: {fileID: 5545478218830425297}
+ m_Layer: 5
+ m_Name: AlarmIcon
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &3374630250525829090
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 7314511769243682470}
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children:
+ - {fileID: 6765948511015989509}
+ - {fileID: 5399931818953919527}
+ - {fileID: 8602533637707951236}
+ m_Father: {fileID: 0}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_AnchorMin: {x: 0.5, y: 0.5}
+ m_AnchorMax: {x: 0.5, y: 0.5}
+ m_AnchoredPosition: {x: 0, y: 0}
+ m_SizeDelta: {x: 100, y: 150}
+ m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &5545478218830425297
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 7314511769243682470}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: cd395cde180b3094a91d87699139bbcf, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ text: {fileID: 2018211268787215362}
+--- !u!1 &8817008079317718099
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 5399931818953919527}
+ - component: {fileID: 1290445261252787132}
+ - component: {fileID: 2283905710529375295}
+ m_Layer: 5
+ m_Name: bg
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &5399931818953919527
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 8817008079317718099}
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 3374630250525829090}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_AnchorMin: {x: 0, y: 0}
+ m_AnchorMax: {x: 1, y: 1}
+ m_AnchoredPosition: {x: 0, y: 0}
+ m_SizeDelta: {x: 0, y: 0}
+ m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &1290445261252787132
+CanvasRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 8817008079317718099}
+ m_CullTransparentMesh: 1
+--- !u!114 &2283905710529375295
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 8817008079317718099}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_Material: {fileID: 0}
+ m_Color: {r: 1, g: 1, b: 1, a: 1}
+ m_RaycastTarget: 1
+ m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+ m_Maskable: 1
+ m_OnCullStateChanged:
+ m_PersistentCalls:
+ m_Calls: []
+ m_Sprite: {fileID: -895992892, guid: 73d757b5d1b754245969af12daf01e78, type: 3}
+ m_Type: 1
+ m_PreserveAspect: 0
+ m_FillCenter: 1
+ m_FillMethod: 4
+ m_FillAmount: 1
+ m_FillClockwise: 1
+ m_FillOrigin: 0
+ m_UseSpriteMesh: 0
+ m_PixelsPerUnitMultiplier: 1
diff --git a/Assets/Resources/Prefabs/SampleProject/Factory/AlarmIcon.prefab.meta b/Assets/Resources/Prefabs/SampleProject/Factory/AlarmIcon.prefab.meta
new file mode 100644
index 00000000..3825d7c4
--- /dev/null
+++ b/Assets/Resources/Prefabs/SampleProject/Factory/AlarmIcon.prefab.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: e9acc8c9a93a2b5409fc01661660b217
+PrefabImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Resources/Prefabs/SampleProject/UI/InfoWindow.prefab b/Assets/Resources/Prefabs/SampleProject/UI/InfoWindow.prefab
index cd5c3e12..c2cb37bb 100644
--- a/Assets/Resources/Prefabs/SampleProject/UI/InfoWindow.prefab
+++ b/Assets/Resources/Prefabs/SampleProject/UI/InfoWindow.prefab
@@ -208,6 +208,127 @@ MonoBehaviour:
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
+--- !u!1 &1844102171940980497
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1010396666164740167}
+ - component: {fileID: 380188952969839968}
+ - component: {fileID: 170663812404971233}
+ - component: {fileID: 8791400826399403740}
+ m_Layer: 5
+ m_Name: CopyButton
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &1010396666164740167
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1844102171940980497}
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children:
+ - {fileID: 5059140281209684741}
+ m_Father: {fileID: 4802890858156259540}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_AnchorMin: {x: 1, y: 1}
+ m_AnchorMax: {x: 1, y: 1}
+ m_AnchoredPosition: {x: -20, y: -2}
+ m_SizeDelta: {x: 30, y: 15}
+ m_Pivot: {x: 1, y: 1}
+--- !u!222 &380188952969839968
+CanvasRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1844102171940980497}
+ m_CullTransparentMesh: 1
+--- !u!114 &170663812404971233
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1844102171940980497}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_Material: {fileID: 0}
+ m_Color: {r: 0.26415092, g: 0.26415092, b: 0.26415092, a: 1}
+ m_RaycastTarget: 1
+ m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+ m_Maskable: 1
+ m_OnCullStateChanged:
+ m_PersistentCalls:
+ m_Calls: []
+ m_Sprite: {fileID: -27720893, guid: e5829cbc100001646956a9c3ed4e33c5, type: 3}
+ m_Type: 1
+ m_PreserveAspect: 0
+ m_FillCenter: 1
+ m_FillMethod: 4
+ m_FillAmount: 1
+ m_FillClockwise: 1
+ m_FillOrigin: 0
+ m_UseSpriteMesh: 0
+ m_PixelsPerUnitMultiplier: 1
+--- !u!114 &8791400826399403740
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1844102171940980497}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_Navigation:
+ m_Mode: 3
+ m_WrapAround: 0
+ m_SelectOnUp: {fileID: 0}
+ m_SelectOnDown: {fileID: 0}
+ m_SelectOnLeft: {fileID: 0}
+ m_SelectOnRight: {fileID: 0}
+ m_Transition: 1
+ m_Colors:
+ m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+ m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+ m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+ m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+ m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+ m_ColorMultiplier: 1
+ m_FadeDuration: 0.1
+ m_SpriteState:
+ m_HighlightedSprite: {fileID: 0}
+ m_PressedSprite: {fileID: 0}
+ m_SelectedSprite: {fileID: 0}
+ m_DisabledSprite: {fileID: 0}
+ m_AnimationTriggers:
+ m_NormalTrigger: Normal
+ m_HighlightedTrigger: Highlighted
+ m_PressedTrigger: Pressed
+ m_SelectedTrigger: Selected
+ m_DisabledTrigger: Disabled
+ m_Interactable: 1
+ m_TargetGraphic: {fileID: 170663812404971233}
+ m_OnClick:
+ m_PersistentCalls:
+ m_Calls: []
--- !u!1 &4884066667293879814
GameObject:
m_ObjectHideFlags: 0
@@ -316,6 +437,7 @@ RectTransform:
- {fileID: 7383335062191980062}
- {fileID: 2993317773174661490}
- {fileID: 6308980257678838100}
+ - {fileID: 1010396666164740167}
- {fileID: 6685372230643413407}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
@@ -346,6 +468,7 @@ MonoBehaviour:
m_EditorClassIdentifier:
text: {fileID: 4202672738064507978}
closeButton: {fileID: 5925304901667948221}
+ copyButton: {fileID: 8791400826399403740}
screenOffset: {x: 10, y: 10}
menuBarHeight: 70
--- !u!1 &7346391167643616437
@@ -484,3 +607,139 @@ MonoBehaviour:
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
+--- !u!1 &7999202329282239406
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 5059140281209684741}
+ - component: {fileID: 8801292156144245076}
+ - component: {fileID: 6403130881974049321}
+ m_Layer: 5
+ m_Name: Text (TMP)
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &5059140281209684741
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 7999202329282239406}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 1010396666164740167}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_AnchorMin: {x: 0, y: 0}
+ m_AnchorMax: {x: 1, y: 1}
+ m_AnchoredPosition: {x: 0, y: 0}
+ m_SizeDelta: {x: 0, y: 0}
+ m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &8801292156144245076
+CanvasRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 7999202329282239406}
+ m_CullTransparentMesh: 1
+--- !u!114 &6403130881974049321
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 7999202329282239406}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_Material: {fileID: 0}
+ m_Color: {r: 1, g: 1, b: 1, a: 1}
+ m_RaycastTarget: 1
+ m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+ m_Maskable: 1
+ m_OnCullStateChanged:
+ m_PersistentCalls:
+ m_Calls: []
+ m_text: Copy
+ m_isRightToLeft: 0
+ m_fontAsset: {fileID: 11400000, guid: 08cebd004d97ca742ac80400f37f4eed, type: 2}
+ m_sharedMaterial: {fileID: 4860575619018115804, guid: 08cebd004d97ca742ac80400f37f4eed, type: 2}
+ m_fontSharedMaterials: []
+ m_fontMaterial: {fileID: 0}
+ m_fontMaterials: []
+ m_fontColor32:
+ serializedVersion: 2
+ rgba: 4294967295
+ m_fontColor: {r: 1, g: 1, b: 1, a: 1}
+ m_enableVertexGradient: 0
+ m_colorMode: 3
+ m_fontColorGradient:
+ topLeft: {r: 1, g: 1, b: 1, a: 1}
+ topRight: {r: 1, g: 1, b: 1, a: 1}
+ bottomLeft: {r: 1, g: 1, b: 1, a: 1}
+ bottomRight: {r: 1, g: 1, b: 1, a: 1}
+ m_fontColorGradientPreset: {fileID: 0}
+ m_spriteAsset: {fileID: 0}
+ m_tintAllSprites: 0
+ m_StyleSheet: {fileID: 0}
+ m_TextStyleHashCode: -1183493901
+ m_overrideHtmlColors: 0
+ m_faceColor:
+ serializedVersion: 2
+ rgba: 4294967295
+ m_fontSize: 8
+ m_fontSizeBase: 8
+ m_fontWeight: 400
+ m_enableAutoSizing: 0
+ m_fontSizeMin: 18
+ m_fontSizeMax: 72
+ m_fontStyle: 0
+ m_HorizontalAlignment: 2
+ m_VerticalAlignment: 512
+ m_textAlignment: 65535
+ m_characterSpacing: 0
+ m_wordSpacing: 0
+ m_lineSpacing: 0
+ m_lineSpacingMax: 0
+ m_paragraphSpacing: 0
+ m_charWidthMaxAdj: 0
+ m_TextWrappingMode: 1
+ m_wordWrappingRatios: 0.4
+ m_overflowMode: 0
+ m_linkedTextComponent: {fileID: 0}
+ parentLinkedComponent: {fileID: 0}
+ m_enableKerning: 0
+ m_ActiveFontFeatures: 6e72656b
+ m_enableExtraPadding: 0
+ checkPaddingRequired: 0
+ m_isRichText: 1
+ m_EmojiFallbackSupport: 1
+ m_parseCtrlCharacters: 1
+ m_isOrthographic: 1
+ m_isCullingEnabled: 0
+ m_horizontalMapping: 0
+ m_verticalMapping: 0
+ m_uvLineOffset: 0
+ m_geometrySortingOrder: 0
+ m_IsTextObjectScaleStatic: 0
+ m_VertexBufferAutoSizeReduction: 0
+ m_useMaxVisibleDescender: 1
+ m_pageToDisplay: 1
+ m_margin: {x: 0, y: 0, z: 0, w: 0}
+ m_isUsingLegacyAnimationComponent: 0
+ m_isVolumetricText: 0
+ m_hasFontAssetChanged: 0
+ m_baseMaterial: {fileID: 0}
+ m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
diff --git a/Assets/Scenes/SampleProject.unity b/Assets/Scenes/SampleProject.unity
index 2893f250..53174c5d 100644
--- a/Assets/Scenes/SampleProject.unity
+++ b/Assets/Scenes/SampleProject.unity
@@ -926,6 +926,51 @@ RectTransform:
m_CorrespondingSourceObject: {fileID: 8849628700159893901, guid: 5a23b2bd2bd04c045878e1a06b3b9aa2, type: 3}
m_PrefabInstance: {fileID: 769109585}
m_PrefabAsset: {fileID: 0}
+--- !u!1 &784978156
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 784978157}
+ - component: {fileID: 784978158}
+ m_Layer: 0
+ m_Name: AlarmManager
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &784978157
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 784978156}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 429.2735, y: 488.27496, z: 49.768143}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 0}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &784978158
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 784978156}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 6765c5d969530e44cbe4fc91d5e52ca1, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ alarmUIPrefab: {fileID: 1828762385695490929, guid: e8b88e69e607ee448806427e91440a8e, type: 3}
--- !u!1 &832575517
GameObject:
m_ObjectHideFlags: 0
@@ -980,6 +1025,115 @@ RectTransform:
m_CorrespondingSourceObject: {fileID: 5064510836022735693, guid: 27ddee6261f49584c8634ba7c5f4ae46, type: 3}
m_PrefabInstance: {fileID: 8261569461642068635}
m_PrefabAsset: {fileID: 0}
+--- !u!1 &1091201604
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1091201608}
+ - component: {fileID: 1091201607}
+ - component: {fileID: 1091201606}
+ - component: {fileID: 1091201605}
+ m_Layer: 0
+ m_Name: Plane
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!64 &1091201605
+MeshCollider:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1091201604}
+ m_Material: {fileID: 0}
+ m_IncludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_ExcludeLayers:
+ serializedVersion: 2
+ m_Bits: 0
+ m_LayerOverridePriority: 0
+ m_IsTrigger: 0
+ m_ProvidesContacts: 0
+ m_Enabled: 1
+ serializedVersion: 5
+ m_Convex: 0
+ m_CookingOptions: 30
+ m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!23 &1091201606
+MeshRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1091201604}
+ 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: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2}
+ 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!33 &1091201607
+MeshFilter:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1091201604}
+ m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!4 &1091201608
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1091201604}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 1000, y: 0, z: 1000}
+ m_LocalScale: {x: 300, y: 1, z: 300}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 0}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1101428664
GameObject:
m_ObjectHideFlags: 0
@@ -2069,8 +2223,10 @@ SceneRoots:
- {fileID: 832575519}
- {fileID: 632541407}
- {fileID: 27812499}
+ - {fileID: 784978157}
- {fileID: 2030316712}
- {fileID: 483439351}
- {fileID: 495653798}
- {fileID: 88083293}
- {fileID: 1840728471}
+ - {fileID: 1091201608}
diff --git a/Assets/Scripts/SampleProject/AppMain.cs b/Assets/Scripts/SampleProject/AppMain.cs
index fac28d7d..cc59f3e0 100644
--- a/Assets/Scripts/SampleProject/AppMain.cs
+++ b/Assets/Scripts/SampleProject/AppMain.cs
@@ -52,6 +52,7 @@ namespace SampleProject
mqttPipeLine = new MQTTPipeLine("localhost", 1883);
mqttPipeLine.AddTopic("AGV");
+ //mqttPipeLine.AddTopic("ALARM");
mqttPipeLine.Execute();
//10รส ศฤ มคม๖
diff --git a/Assets/Scripts/SampleProject/SceneMain.cs b/Assets/Scripts/SampleProject/SceneMain.cs
index bfb91e31..75341f79 100644
--- a/Assets/Scripts/SampleProject/SceneMain.cs
+++ b/Assets/Scripts/SampleProject/SceneMain.cs
@@ -1,6 +1,7 @@
๏ปฟusing System;
using UnityEngine;
using UVC.Core;
+using UVC.Factory.Alarm;
using UVC.UI.Tooltip;
namespace SampleProject
@@ -21,6 +22,17 @@ namespace SampleProject
AppMain.Instance.Initialized += OnAppInitialized;
}
+ ///
+ /// AGV ๊ด๋ฆฌ์๊ฐ ์์ฑ๋ ๋ ๋ฐ์ํ๋ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.
+ ///
+ /// ์ด ๋ฉ์๋๋ AGV ๊ด๋ฆฌ์ ์์ฑ๊ณผ ๊ด๋ จ๋ ํ์ํ ์ด๊ธฐํ ๋๋ ์ค์ ์์
์ ์ํํ๊ธฐ ์ํ ๊ฒ์
๋๋ค.
+ /// ๋ด๋ถ์ ์ผ๋ก ํธ์ถ๋๋ฉฐ ์ธ๋ถ ์ฝ๋์์ ์ง์ ์ฌ์ฉํ๋๋ก ์๋๋ ๊ฒ์ด ์๋๋๋ค.
+ ///
+ internal void OnAGVManagerCreated()
+ {
+ AlarmManager.Instance.Run();
+ }
+
private void OnAppInitialized()
{
if (Initialized != null)
diff --git a/Assets/Scripts/UVC/Data/DataArray.cs b/Assets/Scripts/UVC/Data/DataArray.cs
index 0120ed4c..ebdd62f9 100644
--- a/Assets/Scripts/UVC/Data/DataArray.cs
+++ b/Assets/Scripts/UVC/Data/DataArray.cs
@@ -3,6 +3,7 @@ using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
+using UnityEngine;
namespace UVC.Data
{
@@ -11,12 +12,21 @@ namespace UVC.Data
///
public class DataArray : List, IDataObject
{
-
+ private bool isInPool = false;
///
/// ์ด ๊ฐ์ฒด๊ฐ ๊ฐ์ฒด ํ์ ์๋์ง ์ฌ๋ถ๋ฅผ ๋ํ๋
๋๋ค.
/// ์ค๋ณต ๋ฐํ์ ๋ฐฉ์งํ๊ธฐ ์ํด DataArrayPool์์ ๋ด๋ถ์ ์ผ๋ก ์ฌ์ฉ๋ฉ๋๋ค.
///
- internal bool IsInPool { get; set; } = false;
+ internal bool IsInPool { get => isInPool;
+ set
+ {
+ isInPool = value;
+ foreach (var item in this)
+ {
+ item.IsInPool = value; // ๋ด๋ถ DataObject๋ ํ์ ์๋ค๊ณ ํ์ํฉ๋๋ค.
+ }
+ }
+ }
// ์ถ๊ฐ ๋ ํญ๋ชฉ ๋ชฉ๋ก
protected List addedList = new List();
@@ -77,6 +87,26 @@ namespace UVC.Data
}
}
+ public DataArray(System.IO.Stream jsonStream)
+ {
+ if (jsonStream == null)
+ throw new ArgumentNullException(nameof(jsonStream));
+
+ // ์คํธ๋ฆผ ์ฒ๋ฆฌ ์ต์ ํ๋ฅผ ์ํด ์ฒญํฌ ๋จ์๋ก ์ฝ์ ์ ์์ง๋ง,
+ // ํ์ฌ๋ Newtonsoft.Json์ ๊ธฐ๋ณธ ์ญ์ง๋ ฌํ ์ฌ์ฉ
+ using (var reader = new Newtonsoft.Json.JsonTextReader(new System.IO.StreamReader(jsonStream)))
+ {
+ // ์ฒญํฌ ์ฝ๊ธฐ ์ค์ - ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ์ต์ ํ
+ reader.SupportMultipleContent = true;
+
+ var serializer = new Newtonsoft.Json.JsonSerializer();
+ var sourceObject = serializer.Deserialize(reader);
+
+ // ์์ ๋ ์ฝ๋: ์์ฑ์๋ฅผ ํธ์ถํ๋ ๋์ JArray ๋ฉ์๋๋ฅผ ์ฌ์ฉ
+ if (sourceObject != null) FromJArray(sourceObject);
+ }
+ }
+
///
/// JArray๋ก๋ถํฐ DataArray๋ฅผ ์์ฑํ๋ ์์ฑ์
///
@@ -191,8 +221,7 @@ namespace UVC.Data
// ๊ธฐ์กด ๋ณ๊ฒฝ ์ถ์ ๋ชฉ๋ก์ ์ด๊ธฐํํฉ๋๋ค.
ClearTrackedChanges();
-
- // ์ฑ๋ฅ ํฅ์์ ์ํด ID๋ฅผ ํค๋ก ์ฌ์ฉํ๋ ์ฌ์ ์ ์์ฑํฉ๋๋ค.
+
var thisDict = this.ToDictionary(item => item.Id);
var otherDict = otherArray.ToDictionary(item => item.Id);
@@ -208,7 +237,7 @@ namespace UVC.Data
// ์ถ๊ฐ๋ ํญ๋ชฉ ํ์ธ (๋ค๋ฅธ ๋ฐฐ์ด์๋ ์์ง๋ง ํ์ฌ ๋ฐฐ์ด์๋ ์๋ ํญ๋ชฉ)
foreach (var id in otherIds.Where(id => !thisIds.Contains(id)))
{
- addedList.Add(otherDict[id]);
+ addedList.Add(otherDict[id].Copy(fromPool: false));
}
// ์์ ๋ ํญ๋ชฉ ํ์ธ (์์ชฝ ๋ชจ๋์ ์์ง๋ง ๋ด์ฉ์ด ๋ค๋ฅธ ํญ๋ชฉ)
@@ -230,6 +259,12 @@ namespace UVC.Data
// [์ฑ๋ฅ ๊ฐ์ ] RemoveAll๊ณผ HashSet์ ์ฌ์ฉํ์ฌ ์ ๊ฑฐ ์์
์ ํจ์จ์ฑ์ ๋์
๋๋ค.
if (removedList.Count > 0)
{
+ // ์ ๊ฑฐ๋ ๊ฐ์ฒด๋ค์ ๋จผ์ ํ์ ๋ฐํํฉ๋๋ค.
+ foreach (var item in removedList)
+ {
+ if (item.IsInPool) item.ReturnToPool();
+ }
+ // ๊ทธ ๋ค์ ๋ฆฌ์คํธ์์ ์ ๊ฑฐํฉ๋๋ค.
var removedItemIds = new HashSet(removedList.Select(i => i.Id));
this.RemoveAll(item => removedItemIds.Contains(item.Id));
}
@@ -289,11 +324,10 @@ namespace UVC.Data
///
public new void Clear()
{
- if (Count > 0)
- {
- ReturnToDataObjectPool();
- base.Clear();
- }
+ // ๋ด๋ถ ๋ฆฌ์คํธ์ ๋ณ๊ฒฝ ์ถ์ ๋ฆฌ์คํธ๋ฅผ ๋ชจ๋ ๋น์๋๋ค.
+ ReturnToDataObjectPool();
+ base.Clear();
+ ClearTrackedChanges();
}
///
@@ -301,16 +335,12 @@ namespace UVC.Data
///
public void Reset()
{
- // ํฌํจ๋ DataObject๋ค์ ๋จผ์ ํ์ ๋ฐํํฉ๋๋ค.
- ReturnToDataObjectPool();
-
- // ๋ด๋ถ ๋ฆฌ์คํธ์ ๋ณ๊ฒฝ ์ถ์ ๋ฆฌ์คํธ๋ฅผ ๋ชจ๋ ๋น์๋๋ค.
- base.Clear();
- ClearTrackedChanges();
+ Clear();
}
public void ReturnToPool()
{
+ // ํฌํจ๋ DataObject๋ค์ ๋จผ์ ํ์ ๋ฐํํฉ๋๋ค.
DataArrayPool.Return(this);
}
@@ -322,7 +352,7 @@ namespace UVC.Data
{
foreach (var item in this)
{
- DataObjectPool.Return(item);
+ item.ReturnToPool();
}
}
@@ -340,37 +370,53 @@ namespace UVC.Data
/// ๋์ผํ ์ํ์ ๊ฐ์ ๊ฐ์ง ํ์ฌ ๋ฐ์ดํฐ ๊ฐ์ฒด์ ์ ์ธ์คํด์ค๋ฅผ ์์ฑํฉ๋๋ค.
///
/// ๋ณต์ ๋ ๊ฐ์ฒด๋ ์๋ณธ ๊ฐ์ฒด์ ๋
๋ฆฝ์ ์ด๋ฏ๋ก, ํ ๊ฐ์ฒด๋ฅผ ๋ณ๊ฒฝํด๋ ๋ค๋ฅธ ๊ฐ์ฒด์๋ ์ํฅ์ ๋ฏธ์น์ง ์์ต๋๋ค.
- ///
+ ///
+ /// ๊ฐ์ฒด ํ์์ ๋ณต์ ํ ์ง ์ฌ๋ถ๋ฅผ ์ง์ ํฉ๋๋ค. ๊ธฐ๋ณธ๊ฐ์ true์
๋๋ค.
/// ํ์ฌ ๊ฐ์ฒด์ ๋ณต์ฌ๋ณธ์ธ ์ ์ธ์คํด์ค๋ฅผ ๋ฐํํฉ๋๋ค.
- public IDataObject Clone()
+ public IDataObject Clone(bool fromPool = true)
+ {
+ return Copy(fromPool);
+ }
+
+ ///
+ /// ํ์ฌ ์ธ์คํด์ค์ ์์ ๋ฐ ๊ด๋ จ ์ํ๋ฅผ ํฌํจํ ๊น์ ๋ณต์ฌ๋ณธ์ ์์ฑํฉ๋๋ค.
+ ///
+ ///
+ /// ์ด ๋ฉ์๋๋ ํ์ฌ ๋ฐฐ์ด์ ์๋ ๋ชจ๋ ์์์ ๊น์ ๋ณต์ฌ๋ณธ์ ํฌํจํ๋ ์๋ก์ด ์ธ์คํด์ค๋ฅผ ๋ฐํํฉ๋๋ค.
+ /// ๋ณต์ฌ๋ ์ธ์คํด์ค๋ ๋ด๋ถ ๋ชฉ๋ก์์ ์ถ์ ํ๋ ์ถ๊ฐ, ์ ๊ฑฐ ๋๋ ์์ ๋ ์์๋ฅผ ํฌํจํ์ฌ ์๋ณธ ์ธ์คํด์ค์ ์ํ๋ ๋ณต์ ํฉ๋๋ค.
+ ///
+ /// ๊ฐ์ฒด ํ์์ ๋ณต์ ํ ์ง ์ฌ๋ถ๋ฅผ ์ง์ ํฉ๋๋ค. ๊ธฐ๋ณธ๊ฐ์ true์
๋๋ค.
+ /// ํ์ฌ ์ธ์คํด์ค์ ๊น์ ๋ณต์ฌ๋ณธ์ธ ์๋ก์ด ์ธ์คํด์ค๋ฅผ ๋ฐํํฉ๋๋ค.
+
+ public DataArray Copy(bool fromPool = true)
{
// ํ์์ ์ DataArray ์ธ์คํด์ค๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
- var clone = DataArrayPool.Get();
- clone.FromCapacity(this.Count);
+ DataArray clone;
+ if(fromPool) clone = DataArrayPool.Get();
+ else clone = new DataArray();
// ๋ฐฐ์ด์ ๋ชจ๋ DataObject๋ฅผ ์ํํ๋ฉฐ ๊ฐ๊ฐ์ ๋ณต์ ํฉ๋๋ค.
foreach (var item in this)
{
// DataObject์ Clone ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ๊น์ ๋ณต์ฌ๋ฅผ ์ํํ๊ณ ,
// base.Add๋ฅผ ์ฌ์ฉํด ์ถ์ ๋ก์ง ์์ด ์ง์ ์ถ๊ฐํฉ๋๋ค.
- if (item.Clone() is DataObject clonedItem)
+ DataObject clonedItem = item.Copy(fromPool);
+ clone.Add(clonedItem);
+ if (addedList.Contains(item))
{
- clone.Add(clonedItem);
- if (addedList.Contains(item))
- {
- clone.addedList.Add(clonedItem);
- }
- else if (removedList.Contains(item))
- {
- clone.removedList.Add(clonedItem);
- }
- else if (modifiedList.Contains(item))
- {
- clone.modifiedList.Add(clonedItem);
- }
+ clone.addedList.Add(clonedItem);
}
+ else if (removedList.Contains(item))
+ {
+ clone.removedList.Add(clonedItem);
+ }
+ else if (modifiedList.Contains(item))
+ {
+ clone.modifiedList.Add(clonedItem);
+ }
+
}
-
+
return clone;
}
diff --git a/Assets/Scripts/UVC/Data/DataArrayPool.cs b/Assets/Scripts/UVC/Data/DataArrayPool.cs
index 04e2d8ef..a1a2e1e0 100644
--- a/Assets/Scripts/UVC/Data/DataArrayPool.cs
+++ b/Assets/Scripts/UVC/Data/DataArrayPool.cs
@@ -10,7 +10,7 @@ namespace UVC.Data
public static class DataArrayPool
{
private static readonly ConcurrentQueue _pool = new ConcurrentQueue();
- private static int _maxPoolSize = 500; // DataArray๋ DataObject๋ณด๋ค ์๊ฐ ์ ์ ๊ฒ์ด๋ฏ๋ก ๊ธฐ๋ณธ๊ฐ ์กฐ์
+ private static int _maxPoolSize = 100; // DataArray๋ DataObject๋ณด๋ค ์๊ฐ ์ ์ ๊ฒ์ด๋ฏ๋ก ๊ธฐ๋ณธ๊ฐ ์กฐ์
// --- ํต๊ณ์ฉ ํ๋ ---
private static int _inUseCount = 0;
@@ -18,15 +18,16 @@ namespace UVC.Data
private static int _poolMisses = 0;
private static readonly object _statsLock = new object();
- ///
- /// ํ์ ์ต๋ ํฌ๊ธฐ๋ฅผ ์ค์ ํฉ๋๋ค.
- ///
- /// ์ค์ ํ ์ต๋ ํฌ๊ธฐ
- public static void SetMaxPoolSize(int size)
+ static DataArrayPool()
{
- _maxPoolSize = size > 0 ? size : 500;
+ // maxPoolSize๋งํผ์ DataObject ์ธ์คํด์ค๋ฅผ ๋ฏธ๋ฆฌ ์์ฑํ์ฌ ํ์ ์ถ๊ฐํฉ๋๋ค.
+ for (int i = 0; i < _maxPoolSize; i++)
+ {
+ _pool.Enqueue(new DataArray() { IsInPool = true });
+ }
}
+
///
/// ํ์์ DataArray ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์ต๋๋ค. ํ์ด ๋น์ด์์ผ๋ฉด ์๋ก ์์ฑํฉ๋๋ค.
///
@@ -50,17 +51,16 @@ namespace UVC.Data
{
int oldSize = _maxPoolSize;
_maxPoolSize += 100; // ์ฆ๊ฐ๋ ์กฐ์
- Debug.Log($"DataArrayPool size automatically increased from {oldSize} to {_maxPoolSize}. Peak usage: {_peakUsage}");
+ //Debug.Log($"DataArrayPool size automatically increased from {oldSize} to {_maxPoolSize}. Peak usage: {_peakUsage}");
}
}
}
- if(_peakUsage % 100 == 0) Debug.Log($"DataArrayPool stats: {GetStats()}");
+ //if(_peakUsage % 10 == 0) Debug.Log($"DataArrayPool stats: {GetStats()}");
if (fromPool)
{
array.IsInPool = false;
- array.Reset();
}
return fromPool ? array : new DataArray();
}
@@ -93,7 +93,7 @@ namespace UVC.Data
/// ํ ํต๊ณ (์ต๋ ์ฌ์ฉ๋, ํ์ฌ ์ฌ์ฉ๋, ํ ๋น์ด์์ ๋ ์์ฑ ํ์, ํ์ฌ ํ ํฌ๊ธฐ)
public static string GetStats()
{
- return $"Peak Usage: {_peakUsage}, In Use: {_inUseCount}, Misses: {_poolMisses}, Pooled: {_pool.Count}, Max Size: {_maxPoolSize}";
+ return $"์ต๋ ์ฌ์ฉ๋: {_peakUsage}, ํ์ฌ ์ฌ์ฉ๋: {_inUseCount}, ํ ๋น์ด์์ ๋ ์์ฑ ํ์: {_poolMisses}, ํ์ฌ ํ ํฌ๊ธฐ: {_pool.Count}, Max Size: {_maxPoolSize}";
}
///
diff --git a/Assets/Scripts/UVC/Data/DataObject.cs b/Assets/Scripts/UVC/Data/DataObject.cs
index 6c67bb48..0507e629 100644
--- a/Assets/Scripts/UVC/Data/DataObject.cs
+++ b/Assets/Scripts/UVC/Data/DataObject.cs
@@ -49,12 +49,30 @@ namespace UVC.Data
///
public class DataObject : OrderedDictionary, IDataObject
{
-
+ private bool isInPool = false;
///
/// ์ด ๊ฐ์ฒด๊ฐ ๊ฐ์ฒด ํ์ ์๋์ง ์ฌ๋ถ๋ฅผ ๋ํ๋
๋๋ค.
/// ์ค๋ณต ๋ฐํ์ ๋ฐฉ์งํ๊ธฐ ์ํด DataObjectPool์์ ๋ด๋ถ์ ์ผ๋ก ์ฌ์ฉ๋ฉ๋๋ค.
///
- internal bool IsInPool { get; set; } = false;
+ internal bool IsInPool
+ {
+ get => isInPool;
+ set
+ {
+ isInPool = value;
+ foreach (var item in this)
+ {
+ if(item.Value is DataObject dataObject)
+ {
+ dataObject.isInPool = value; // ๋ด๋ถ DataObject๋ ํ์ ์๋ค๊ณ ํ์ํฉ๋๋ค.
+ }
+ else if(item.Value is DataArray dataArray)
+ {
+ dataArray.IsInPool = value; // ๋ด๋ถ DataArray๋ ํ์ ์๋ค๊ณ ํ์ํฉ๋๋ค.
+ }
+ }
+ }
+ }
///
/// ๊ฐ์ฒด์ ๊ณ ์ ์๋ณ์๋ฅผ ๋ํ๋ด๋ ์์ฑ์
๋๋ค. DataArray์์ ๋ฐ์ดํฐ๋ฅผ ์๋ณํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
@@ -104,6 +122,30 @@ namespace UVC.Data
///
public DataObject() { }
+ public DataObject(string jsonString): this(JObject.Parse(jsonString))
+ {
+ }
+
+ public DataObject(System.IO.Stream jsonStream)
+ {
+ if (jsonStream == null)
+ throw new ArgumentNullException(nameof(jsonStream));
+
+ // ์คํธ๋ฆผ ์ฒ๋ฆฌ ์ต์ ํ๋ฅผ ์ํด ์ฒญํฌ ๋จ์๋ก ์ฝ์ ์ ์์ง๋ง,
+ // ํ์ฌ๋ Newtonsoft.Json์ ๊ธฐ๋ณธ ์ญ์ง๋ ฌํ ์ฌ์ฉ
+ using (var reader = new Newtonsoft.Json.JsonTextReader(new System.IO.StreamReader(jsonStream)))
+ {
+ // ์ฒญํฌ ์ฝ๊ธฐ ์ค์ - ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ์ต์ ํ
+ reader.SupportMultipleContent = true;
+
+ var serializer = new Newtonsoft.Json.JsonSerializer();
+ var sourceObject = serializer.Deserialize(reader);
+
+ // ์์ ๋ ์ฝ๋: ์์ฑ์๋ฅผ ํธ์ถํ๋ ๋์ FromJObject ๋ฉ์๋๋ฅผ ์ฌ์ฉ
+ if(sourceObject != null) FromJObject(sourceObject);
+ }
+ }
+
///
/// JObject๋ก๋ถํฐ ๋ฐ์ดํฐ ๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค.
///
@@ -270,6 +312,16 @@ namespace UVC.Data
if (hasChanged)
{
+ // ๊ธฐ์กด์ ํ๋ง ๊ฐ๋ฅํ ๊ฐ์ฒด๊ฐ ์์๋ค๋ฉด ํ์ ๋ฐํํฉ๋๋ค.
+ if (oldValue is DataObject oldDataObject)
+ {
+ if(oldDataObject.IsInPool) oldDataObject.ReturnToPool();
+ }
+ else if (oldValue is DataArray oldDataArray)
+ {
+ if (oldDataArray.IsInPool) oldDataArray.ReturnToPool();
+ }
+
// ๊ธฐ๋ณธ ๋์
๋๋ฆฌ์ ๊ฐ์ ์ค์ ํฉ๋๋ค.
base[key] = value;
@@ -289,7 +341,7 @@ namespace UVC.Data
/// ์์ฑ ์ด๋ฆ
/// ์์ฑ์ด ์๊ฑฐ๋ ๋ณํํ ์ ์๋ ๊ฒฝ์ฐ ๋ฐํํ ๊ธฐ๋ณธ๊ฐ
/// ๋ณํ๋ ์ ์ ๊ฐ ๋๋ ๊ธฐ๋ณธ๊ฐ
- public int GetInt(string propertyName, int defaultValue = 0)
+ public int? GetInt(string propertyName, int? defaultValue = null)
{
if (TryGetValue(propertyName, out object? value) && value != null)
{
@@ -321,7 +373,7 @@ namespace UVC.Data
/// ์์ฑ ์ด๋ฆ
/// ์์ฑ์ด ์๊ฑฐ๋ ๋ณํํ ์ ์๋ ๊ฒฝ์ฐ ๋ฐํํ ๊ธฐ๋ณธ๊ฐ
/// ๋ณํ๋ ๋ถ๋ฆฌ์ธ ๊ฐ ๋๋ ๊ธฐ๋ณธ๊ฐ
- public bool GetBool(string propertyName, bool defaultValue = false)
+ public bool? GetBool(string propertyName, bool? defaultValue = false)
{
if (TryGetValue(propertyName, out object? value) && value != null)
{
@@ -338,7 +390,7 @@ namespace UVC.Data
/// ์์ฑ ์ด๋ฆ
/// ์์ฑ์ด ์๊ฑฐ๋ ๋ณํํ ์ ์๋ ๊ฒฝ์ฐ ๋ฐํํ ๊ธฐ๋ณธ๊ฐ
/// ๋ณํ๋ ๋ถ๋ ์์์ ๊ฐ ๋๋ ๊ธฐ๋ณธ๊ฐ
- public float GetFloat(string propertyName, float defaultValue = 0f)
+ public float? GetFloat(string propertyName, float? defaultValue = null)
{
if (TryGetValue(propertyName, out object? value) && value != null)
{
@@ -355,7 +407,7 @@ namespace UVC.Data
/// ์์ฑ ์ด๋ฆ
/// ์์ฑ์ด ์๊ฑฐ๋ ๋ณํํ ์ ์๋ ๊ฒฝ์ฐ ๋ฐํํ ๊ธฐ๋ณธ๊ฐ
/// ๋ณํ๋ ๋๋ธ ๊ฐ ๋๋ ๊ธฐ๋ณธ๊ฐ
- public double GetDouble(string propertyName, double defaultValue = 0.0)
+ public double? GetDouble(string propertyName, double? defaultValue = null)
{
if (TryGetValue(propertyName, out object? value) && value != null)
{
@@ -372,7 +424,7 @@ namespace UVC.Data
/// ์์ฑ ์ด๋ฆ
/// ์์ฑ์ด ์๊ฑฐ๋ ๋ณํํ ์ ์๋ ๊ฒฝ์ฐ ๋ฐํํ ๊ธฐ๋ณธ๊ฐ
/// ๋ณํ๋ long ๊ฐ ๋๋ ๊ธฐ๋ณธ๊ฐ
- public long GetLong(string propertyName, long defaultValue = 0L)
+ public long? GetLong(string propertyName, long? defaultValue = null)
{
if (TryGetValue(propertyName, out object? value) && value != null)
{
@@ -407,7 +459,7 @@ namespace UVC.Data
/// ์์ฑ ์ด๋ฆ
/// ์์ฑ์ด ์๊ฑฐ๋ ๋ณํํ ์ ์๋ ๊ฒฝ์ฐ ๋ฐํํ ๊ธฐ๋ณธ๊ฐ
/// ๋ณํ๋ ์ด๊ฑฐํ ๊ฐ ๋๋ ๊ธฐ๋ณธ๊ฐ
- public T GetEnum(string propertyName, T defaultValue = default) where T : Enum
+ public T? GetEnum(string propertyName, T? defaultValue = default) where T : Enum
{
if (TryGetValue(propertyName, out object? value) && value != null)
{
@@ -572,9 +624,22 @@ namespace UVC.Data
/// ์ ๊ฑฐ ์ฑ๊ณต ์ฌ๋ถ
public new bool Remove(string key)
{
+ // ์ ๊ฑฐํ๊ธฐ ์ ์ ์ด์ ๊ฐ์ ๊ฐ์ ธ์ต๋๋ค.
+ TryGetValue(key, out object? oldValue);
+
bool result = base.Remove(key);
if (result)
{
+ // ์ ๊ฑฐ๋ ๊ฐ์ฒด๊ฐ ํ๋ง ๊ฐ๋ฅํ ๊ฒฝ์ฐ ํ์ ๋ฐํํฉ๋๋ค.
+ if (oldValue is DataObject dataObject)
+ {
+ if(dataObject.IsInPool) dataObject.ReturnToPool();
+ }
+ else if (oldValue is DataArray dataArray)
+ {
+ if (dataArray.IsInPool) dataArray.ReturnToPool();
+ }
+
// ๋ณ๊ฒฝ ์ถ์ ๋ชฉ๋ก์์๋ ์ ๊ฑฐํฉ๋๋ค.
changedProperies.Remove(key);
}
@@ -586,6 +651,17 @@ namespace UVC.Data
///
public void RemoveAll()
{
+ foreach (var value in Values.ToList())
+ {
+ if(value is DataObject dataObject)
+ {
+ dataObject.ReturnToPool(); // DataObject๋ฅผ ํ์ ๋ฐํํฉ๋๋ค.
+ }
+ else if (value is DataArray dataArray)
+ {
+ dataArray.ReturnToPool(); // DataArray๋ฅผ ํ์ ๋ฐํํฉ๋๋ค.
+ }
+ }
base.Clear();
changedProperies.Clear();
}
@@ -606,10 +682,27 @@ namespace UVC.Data
///
/// ๋ณต์ ๋ ๊ฐ์ฒด๋ ์๋ณธ ๊ฐ์ฒด์ ๋
๋ฆฝ์ ์ด๋ฏ๋ก, ํ ๊ฐ์ฒด๋ฅผ ๋ณ๊ฒฝํด๋ ๋ค๋ฅธ ๊ฐ์ฒด์๋ ์ํฅ์ ๋ฏธ์น์ง ์์ต๋๋ค.
///
+ /// ๋ณต์ ๋ ๊ฐ์ฒด๊ฐ ํ์ ์๋์ง ์ฌ๋ถ๋ฅผ ๋ํ๋
๋๋ค. ๊ธฐ๋ณธ๊ฐ์ true์
๋๋ค.
/// ํ์ฌ ๊ฐ์ฒด์ ๋ณต์ฌ๋ณธ์ธ ์ ์ธ์คํด์ค๋ฅผ ๋ฐํํฉ๋๋ค.
- public IDataObject Clone()
+ public IDataObject Clone(bool fromPool = true)
{
- var clone = DataObjectPool.Get();
+ return Copy(fromPool);
+ }
+
+ ///
+ /// ๋ชจ๋ ํค-๊ฐ ์์ ํฌํจํ์ฌ ํ์ฌ ์ธ์คํด์ค์ ๊น์ ๋ณต์ฌ๋ณธ์ ์์ฑํฉ๋๋ค.
+ ///
+ /// ์ด ๋ฉ์๋๋ ์ ๊ทธ ๋ด์ฉ์ ๊น์ ๋ณต์ฌ๋ณธ์ ์ํํฉ๋๋ค.
+ /// ํค-๊ฐ ์์ ๊ฐ์ด ๋ค๋ฅธ ๋๋ ์ธ ๊ฒฝ์ฐ,
+ /// ๋ฉ์๋๋ ํด๋น ๊ฐ์ฒด๋ฅผ ์ฌ๊ท์ ์ผ๋ก ๋ณต์ ํฉ๋๋ค. ๊ธฐ๋ณธ ์ ํ ๋ฐ ๊ธฐํ ๋ณต์ ๋ถ๊ฐ๋ฅํ ๊ฐ์
+ /// ์ง์ ๋ณต์ฌ๋ฉ๋๋ค.
+ /// ๋ณต์ ๋ ๊ฐ์ฒด๊ฐ ํ์ ์๋์ง ์ฌ๋ถ๋ฅผ ๋ํ๋
๋๋ค. ๊ธฐ๋ณธ๊ฐ์ true์
๋๋ค.
+ /// ํ์ฌ ๊ฐ์ฒด์ ๊น์ ๋ณต์ฌ๋ณธ์ธ ์๋ก์ด ์ธ์คํด์ค๋ฅผ ๋ฐํํฉ๋๋ค.
+ public DataObject Copy(bool fromPool = true)
+ {
+ DataObject clone = DataObjectPool.Get();
+ if(fromPool) clone = DataObjectPool.Get();
+ else clone = new DataObject();
clone.Name = Name;
clone.IdKey = IdKey;
@@ -619,13 +712,13 @@ namespace UVC.Data
object? clonedValue;
switch (pair.Value)
{
- // ๊ฐ์ด DataObject์ธ ๊ฒฝ์ฐ, ์ฌ๊ท์ ์ผ๋ก Clone์ ํธ์ถํฉ๋๋ค.
+ // ๊ฐ์ด DataObject์ธ ๊ฒฝ์ฐ, ์ฌ๊ท์ ์ผ๋ก Copy์ ํธ์ถํฉ๋๋ค.
case DataObject dataObjectValue:
- clonedValue = dataObjectValue.Clone();
+ clonedValue = dataObjectValue.Copy(fromPool);
break;
// ๊ฐ์ด DataArray์ธ ๊ฒฝ์ฐ, ์ฌ๊ท์ ์ผ๋ก Clone์ ํธ์ถํฉ๋๋ค.
case DataArray dataArrayValue:
- clonedValue = dataArrayValue.Clone();
+ clonedValue = dataArrayValue.Copy(fromPool);
break;
// ๊ทธ ์ธ์ ๊ฒฝ์ฐ (primitive ํ์
๋ฑ)๋ ๊ทธ๋๋ก ๋ณต์ฌํฉ๋๋ค.
default:
@@ -684,7 +777,23 @@ namespace UVC.Data
|| (this[keyValue.Key] != null && keyValue.Value == null)
|| (this[keyValue.Key] != null && keyValue.Value != null && !this[keyValue.Key]!.Equals(keyValue.Value)))
{
- this[keyValue.Key] = keyValue.Value;
+ //์ฐธ์กฐ ํ์
๊ณผ ๊ฐ ํ์
๊ตฌ๋ถํ์ฌ ๋ณต์ฌ
+ object? valueToSet;
+ switch (keyValue.Value)
+ {
+ // DataObject๋ DataArray๋ ํ์ ์ฌ์ฉํ์ง ์๋ ๊น์ ๋ณต์ฌ๋ฅผ ์ํํฉ๋๋ค.
+ case DataObject dataObjectValue:
+ valueToSet = dataObjectValue.Copy(fromPool: false);
+ break;
+ case DataArray dataArrayValue:
+ valueToSet = dataArrayValue.Copy(fromPool: false);
+ break;
+ // ๊ทธ ์ธ ํ์
์ ๊ฐ์ ๊ทธ๋๋ก ํ ๋นํฉ๋๋ค.
+ default:
+ valueToSet = keyValue.Value;
+ break;
+ }
+ this[keyValue.Key] = valueToSet;
changedProperies.Add(keyValue.Key);
}
}
diff --git a/Assets/Scripts/UVC/Data/DataObjectPool.cs b/Assets/Scripts/UVC/Data/DataObjectPool.cs
index 78802002..62341663 100644
--- a/Assets/Scripts/UVC/Data/DataObjectPool.cs
+++ b/Assets/Scripts/UVC/Data/DataObjectPool.cs
@@ -22,7 +22,7 @@ namespace UVC.Data
/// obj["age"] = 30;
///
/// // ์์
์๋ฃ ํ ํ์ ๋ฐํ
- /// DataObjectPool.Return(obj);
+ /// obj.ReturnToPool();
///
/// // ํ ํต๊ณ ํ์ธ
/// ULog.Debug(DataObjectPool.GetStats());
@@ -33,27 +33,26 @@ namespace UVC.Data
///
/// DataObject ์ธ์คํด์ค๋ฅผ ์ ์ฅํ๋ ์ค๋ ๋ ์์ ํ์
๋๋ค.
///
- private static ConcurrentQueue dataObjectPool = new ConcurrentQueue();
+ private static ConcurrentQueue pool = new ConcurrentQueue();
///
/// ํ์ ์ต๋ ํฌ๊ธฐ์
๋๋ค. ์ด ํฌ๊ธฐ๋ฅผ ์ด๊ณผํ๋ ๊ฐ์ฒด๋ ํ์ ์ ์ฅ๋์ง ์์ต๋๋ค.
///
- private static int maxPoolSize = 1000;
+ private static int maxPoolSize = 4000;
// --- ํต๊ณ์ฉ ํ๋ ---
- private static int _inUseCount = 0;
- private static int _peakUsage = 0;
- private static int _poolMisses = 0;
+ private static int _inUseCount = 0; // ํ์ฌ ์ฌ์ฉ ์ค์ธ DataObject ์ธ์คํด์ค์ ์
+ private static int _peakUsage = 0; // ์ต๋ ์ฌ์ฉ๋ ๊ธฐ๋ก
+ private static int _poolMisses = 0; // ํ์์ ๊ฐ์ฒด๋ฅผ ์ฐพ์ง ๋ชปํ๊ณ ์๋ก ์์ฑํ ํ์
private static readonly object _statsLock = new object();
-
- ///
- /// ํ์ ์ต๋ ํฌ๊ธฐ๋ฅผ ์ค์ ํฉ๋๋ค.
- ///
- /// ์ค์ ํ ์ต๋ ํฌ๊ธฐ
- public static void SetMaxPoolSize(int size)
+ static DataObjectPool()
{
- maxPoolSize = size > 0 ? size : 1000;
+ // maxPoolSize๋งํผ์ DataObject ์ธ์คํด์ค๋ฅผ ๋ฏธ๋ฆฌ ์์ฑํ์ฌ ํ์ ์ถ๊ฐํฉ๋๋ค.
+ for (int i = 0; i < maxPoolSize; i++)
+ {
+ pool.Enqueue(new DataObject() { IsInPool = true });
+ }
}
///
@@ -63,7 +62,7 @@ namespace UVC.Data
/// ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ DataObject ์ธ์คํด์ค
public static DataObject Get()
{
- bool fromPool = dataObjectPool.TryDequeue(out var obj);
+ bool fromPool = pool.TryDequeue(out var obj);
lock (_statsLock)
{
@@ -82,17 +81,16 @@ namespace UVC.Data
{
int oldSize = maxPoolSize;
maxPoolSize += 1000;
- Debug.Log($"DataObjectPool size automatically increased from {oldSize} to {maxPoolSize}. Peak usage: {_peakUsage}");
+ //Debug.Log($"DataObjectPool size automatically increased from {oldSize} to {maxPoolSize}. Peak usage: {_peakUsage}");
}
}
}
- if (_peakUsage % 100 == 0) Debug.Log($"DataObjectPool stats: {GetStats()}");
+ //if (_peakUsage % 100 == 0) Debug.Log($"DataObjectPool stats: {GetStats()}");
if (fromPool)
{
obj.IsInPool = false;
- obj.Reset();
}
return fromPool ? obj : new DataObject();
}
@@ -111,11 +109,11 @@ namespace UVC.Data
_inUseCount--;
}
- if (dataObjectPool.Count < maxPoolSize)
+ if (pool.Count < maxPoolSize)
{
obj.Reset(); // ์ฌ์ฌ์ฉ ์ ์๋ฒฝํ ์ด๊ธฐํ
obj.IsInPool = true;
- dataObjectPool.Enqueue(obj);
+ pool.Enqueue(obj);
}
// ํ์ด ๊ฐ๋ ์ฐจ๋ฉด ๊ฐ์ฒด๋ ํ์ ์ถ๊ฐ๋์ง ์๊ณ GC ๋์์ด ๋ฉ๋๋ค.
}
@@ -126,7 +124,7 @@ namespace UVC.Data
/// ํ ํต๊ณ (์ต๋ ์ฌ์ฉ๋, ํ์ฌ ์ฌ์ฉ๋, ํ ๋น์ด์์ ๋ ์์ฑ ํ์, ํ์ฌ ํ ํฌ๊ธฐ)
public static string GetStats()
{
- return $"Peak Usage: {_peakUsage}, In Use: {_inUseCount}, Misses: {_poolMisses}, Pooled: {dataObjectPool.Count}, Max Size: {maxPoolSize}";
+ return $"์ต๋ ์ฌ์ฉ๋: {_peakUsage}, ํ์ฌ ์ฌ์ฉ๋: {_inUseCount}, ํ ๋น์ด์์ ๋ ์์ฑ ํ์: {_poolMisses}, ํ์ฌ ํ ํฌ๊ธฐ: {pool.Count}, Max Size: {maxPoolSize}";
}
///
diff --git a/Assets/Scripts/UVC/Data/DataRepository.cs b/Assets/Scripts/UVC/Data/DataRepository.cs
index a5f365e2..1f9f9f10 100644
--- a/Assets/Scripts/UVC/Data/DataRepository.cs
+++ b/Assets/Scripts/UVC/Data/DataRepository.cs
@@ -69,7 +69,8 @@ namespace UVC.Data
{
if (!dataObjects.ContainsKey(key))
{
- var newData = dataObject.Clone();
+ var newData = dataObject.Clone(false);
+
dataObjects.Add(key, newData);
dataObject.MarkAllAsUpdated();
//UniTask.Post(() => NotifyDataUpdate(key, newData));
diff --git a/Assets/Scripts/UVC/Data/HttpPipeLine.cs b/Assets/Scripts/UVC/Data/HttpPipeLine.cs
index bfc9c2d8..a684b51b 100644
--- a/Assets/Scripts/UVC/Data/HttpPipeLine.cs
+++ b/Assets/Scripts/UVC/Data/HttpPipeLine.cs
@@ -327,6 +327,10 @@ namespace UVC.Data
mappedObject = info.DataMapper.Map(source);
}
}
+ else
+ {
+ mappedObject = new DataObject(result);
+ }
}
else if (result.StartsWith("["))
{
@@ -403,6 +407,11 @@ namespace UVC.Data
}
}
}
+ else
+ {
+ // DataMapper๊ฐ ์๋ ๊ฒฝ์ฐ, JArray๋ฅผ IDataObject๋ก ๋ณํ
+ mappedObject = new DataArray(result);
+ }
}
}
catch (JsonException ex)
diff --git a/Assets/Scripts/UVC/Data/IDataObject.cs b/Assets/Scripts/UVC/Data/IDataObject.cs
index b62d96e5..80ed6238 100644
--- a/Assets/Scripts/UVC/Data/IDataObject.cs
+++ b/Assets/Scripts/UVC/Data/IDataObject.cs
@@ -41,8 +41,9 @@
///
/// ๋ณต์ ๋ ๊ฐ์ฒด๋ ์๋ณธ ๊ฐ์ฒด์ ๋
๋ฆฝ์ ์ด๋ฏ๋ก, ํ ๊ฐ์ฒด๋ฅผ ๋ณ๊ฒฝํด๋ ๋ค๋ฅธ ๊ฐ์ฒด์๋ ์ํฅ์ ๋ฏธ์น์ง ์์ต๋๋ค.
///
+ /// ๊ฐ์ฒด ํ์์ ๋ณต์ ํ ์ง ์ฌ๋ถ๋ฅผ ์ง์ ํฉ๋๋ค. ๊ธฐ๋ณธ๊ฐ์ true์
๋๋ค.
/// ํ์ฌ ๊ฐ์ฒด์ ๋ณต์ฌ๋ณธ์ธ ์ ์ธ์คํด์ค๋ฅผ ๋ฐํํฉ๋๋ค.
- public IDataObject Clone();
+ public IDataObject Clone(bool fromPool = true);
///
diff --git a/Assets/Scripts/UVC/Data/MQTTPipeLine.cs b/Assets/Scripts/UVC/Data/MQTTPipeLine.cs
index 7471a2ca..b6dcc377 100644
--- a/Assets/Scripts/UVC/Data/MQTTPipeLine.cs
+++ b/Assets/Scripts/UVC/Data/MQTTPipeLine.cs
@@ -198,6 +198,7 @@ namespace UVC.Data
// ๋ฉ์์ง ์ฒ๋ฆฌ๋ฅผ ๋ฐฑ๊ทธ๋ผ์ด๋ ์ค๋ ๋์์ ์คํํ์ฌ ๋ฉ์ธ ์ค๋ ๋ ๋ถํ๋ฅผ ์ค์
๋๋ค.
UniTask.RunOnThreadPool(() =>
{
+ // ํ ํฝ์ด infoList์ readyHandlerList์ ์กด์ฌํ๊ณ , ์ค๋น ์ํ๊ฐ true์ธ ๊ฒฝ์ฐ์๋ง ์ฒ๋ฆฌํฉ๋๋ค.
if (infoList.ContainsKey(topic))
{
MQTTPipeLineInfo info = infoList[topic];
@@ -211,7 +212,14 @@ namespace UVC.Data
{
JObject source = JObject.Parse(message);
if (info.Validator != null && !info.Validator.IsValid(source)) return;
- if (info.DataMapper != null) mappedObject = info.DataMapper.Map(source);
+ if (info.DataMapper != null)
+ {
+ mappedObject = info.DataMapper.Map(source);
+ }
+ else {
+ // DataMapper๊ฐ ์์ผ๋ฉด JObject๋ฅผ IDataObject๋ก ๋ณํ
+ mappedObject = new DataObject(source);
+ }
}
else if (message.StartsWith("["))
{
@@ -223,7 +231,15 @@ namespace UVC.Data
if (validSource == null || validSource.Count == 0) return;
source = validSource;
}
- if (info.DataMapper != null) mappedObject = info.DataMapper.Map(source);
+ if (info.DataMapper != null)
+ {
+ mappedObject = info.DataMapper.Map(source);
+ }
+ else
+ {
+ // DataMapper๊ฐ ์์ผ๋ฉด JArray๋ฅผ IDataObject๋ก ๋ณํ
+ mappedObject = new DataArray(source);
+ }
}
if (mappedObject == null) return;
diff --git a/Assets/Scripts/UVC/Factory/Alarm/AlarmManager.cs b/Assets/Scripts/UVC/Factory/Alarm/AlarmManager.cs
index 69bbe009..1c924d2f 100644
--- a/Assets/Scripts/UVC/Factory/Alarm/AlarmManager.cs
+++ b/Assets/Scripts/UVC/Factory/Alarm/AlarmManager.cs
@@ -1,81 +1,197 @@
-๏ปฟusing System;
+๏ปฟ#nullable enable
+
+using SampleProject;
+using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using UnityEngine;
-using UVC.Factory;
+using UVC.Core;
+using UVC.Data;
+using UVC.Extention;
using UVC.Factory.Component;
namespace UVC.Factory.Alarm
{
- public class AlarmManager : MonoBehaviour
+ public class AlarmManager : SingletonScene
{
- public static AlarmManager Instance { get; private set; }
-
+ [Tooltip("์๋ UI ํ๋ฆฌํน์
๋๋ค. ์ด ํ๋ฆฌํน์ ์๋ ์ ๋ณด๋ฅผ ํ์ํ๋ UI ์์๋ฅผ ํฌํจํด์ผ ํฉ๋๋ค.")]
public GameObject alarmUIPrefab; // ์๋ UI ํ๋ฆฌํน (์๋์์ ์ค๋ช
)
private Dictionary activeAlarmUIs = new Dictionary();
// FactoryDataManager์์ ์ฐพ์ ์ ์๋๋ก ์ฐธ์กฐ๋ฅผ ์ ์ฅ
- private FactoryObjectManager dataManager;
+ private FactoryObjectManager? dataManager;
- void Awake()
+ ///
+ /// AlarmManager์ ์ด๊ธฐํ ๋ฉ์๋์
๋๋ค.
+ /// Awake ๋ฉ์๋์์ ํธ์ถ๋๋ฉฐ, MonoBehaviour๊ฐ ์์ฑ๋ ๋ ํ ๋ฒ๋ง ์คํ๋ฉ๋๋ค.
+ ///
+ protected override void Init()
{
- Instance = this;
+ SceneMain.Instance.Initialized += OnSceneInitialized;
}
- void Start()
+ private void OnSceneInitialized()
{
dataManager = FactoryObjectManager.Instance;
- // ์์: FactoryDataManager์ ์๋ ์ด๋ฒคํธ์ ๊ตฌ๋
- // dataManager.OnAlarmReceived += HandleNewAlarm;
- // dataManager.OnAlarmCleared += HandleClearedAlarm;
}
- public void HandleNewAlarm(AlarmData data)
+ ///
+ /// Alarm ๋ฐ์ดํฐ๋ฅผ ์์ ํ๊ธฐ ์ํ MQTT ํ์ดํ๋ผ์ธ์ ์ค์ ํฉ๋๋ค.
+ ///
+ public void Run()
{
+ //๋ฐ์ดํฐ๋ฅผ ์ด๋ค ํ์์ผ๋ก ๋ฐ์์ง ์ ์ํฉ๋๋ค.
+ var dataMask = new DataMask();
+ dataMask.ObjectName = "Alarm"; // Alarm ๊ฐ์ฒด์ ์ด๋ฆ์ ์ค์ ํฉ๋๋ค.
+ dataMask.ObjectIdKey = "ID"; // Alarm์ ๊ณ ์ ์๋ณ์๋ก ์ฌ์ฉํ ํค๋ฅผ ์ค์ ํฉ๋๋ค.
+ dataMask["ID"] = "";
+ dataMask["ALARM_TYPE"] = "";
+ dataMask["LEVEL"] = "";
+ dataMask["LOGISTIC"] = "";
+ dataMask["STATE"] = "";
+ dataMask["MESSAGE"] = "";
+ dataMask["CODE"] = "";
+ dataMask["ICON"] = "";
+ dataMask["MACHINENAME"] = "";
+ dataMask["SHOPNAME"] = "";
+ dataMask["TRANSPORT_EQP_NAME"] = "";
+ dataMask["TRANSPORT_UNIT_NAME"] = "";
+ dataMask["TRANSPORT_EQP_ID"] = "";
+ dataMask["TRANSPORT_UNIT_ID"] = "";
+ dataMask["SET_TIME"] = DateTime.Now;
+ dataMask["UPDATE_TIME"] = DateTime.Now;
+ dataMask["TIMESTAMP"] = DateTime.Now;
+
+ // MQTT ํ์ดํ๋ผ์ธ ์ ๋ณด๋ฅผ ์์ฑํฉ๋๋ค.
+ // 'ALARM' ํ ํฝ์ ๊ตฌ๋
ํ๊ณ , ๋ฐ์ ๋ฐ์ดํฐ๋ ์์์ ์ ์ํ dataMask๋ก ๋งคํํ๋ฉฐ,
+ // ๋ฐ์ดํฐ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ํด DataValidator๋ฅผ ์ค์ ํฉ๋๋ค.
+ // ๋ฐ์ดํฐ๊ฐ ์
๋ฐ์ดํธ๋๋ฉด OnUpdateData ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ์ฒ๋ฆฌํฉ๋๋ค.
+
+ DataValidator validator = new DataValidator();
+ validator.AddValidator("MACHINENAME", value => value != null);
+
+ var pipelineInfo = new MQTTPipeLineInfo("ALARM")
+ .setDataMapper(new DataMapper(dataMask))
+ .setValidator(validator)
+ .setHandler(OnUpdateData);
+
+ // ์์ฑํ ํ์ดํ๋ผ์ธ ์ ๋ณด๋ฅผ ์ ์ญ MQTT ํ์ดํ๋ผ์ธ์ ์ถ๊ฐํฉ๋๋ค.
+ AppMain.Instance.MQTTPipeLine.Add(pipelineInfo);
+ }
+ ///
+ /// ๋ฐ์ดํฐ ์์ ์ ํธ์ถ๋๋ ๊ณต๊ฐ ํธ๋ค๋ฌ์
๋๋ค.
+ /// ์์ ๋ ALARM ๋ฐ์ดํฐ ๋ฐฐ์ด์ ๋น๋๊ธฐ์ ์ผ๋ก ์ฒ๋ฆฌํ์ฌ ์ฌ์ ๋ฐ์ํฉ๋๋ค.
+ /// ์ถ๊ฐ, ์ ๊ฑฐ, ์์ ๋ ALARM ๋ฐ์ดํฐ๋ฅผ ๊ฐ๊ฐ ๊ตฌ๋ถํ์ฌ ์ฒ๋ฆฌํฉ๋๋ค.
+ ///
+ /// ์์ ๋ ๋ฐ์ดํฐ ๊ฐ์ฒด (DataArray ํํ)
+ public void OnUpdateData(IDataObject? data)
+ {
+
+ if (data == null) return;
+
+ DataArray? arr = data as DataArray;
+ if (arr == null) return;
+ if (arr.Count == 0)
+ {
+ arr.ReturnToPool();
+ return;
+ }
+
+ // ๋ฐ์ดํฐ ๋ฐฐ์ด์์ ์ถ๊ฐ, ์ ๊ฑฐ, ์์ ๋ ํญ๋ชฉ ๋ฆฌ์คํธ๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
+ var AddedItems = arr.AddedItems;
+ var RemovedItems = arr.RemovedItems;
+ var ModifiedList = arr.ModifiedList;
+
+ Debug.Log($"AlarmManager OnUpdateData: Added={AddedItems.Count}, Removed={RemovedItems.Count}, Modified={ModifiedList.Count}");
+
+ // ์๋ก ์ถ๊ฐ๋ ALARM ์ฒ๋ฆฌ
+ foreach (var item in AddedItems.ToList())
+ {
+ HandleNewAlarm(item.Copy());
+ }
+
+ // ์ ๊ฑฐ๋ ALARM ์ฒ๋ฆฌ
+ foreach (var item in RemovedItems.ToList())
+ {
+ HandleClearedAlarm(item.Copy());
+ }
+
+ // ์ ๋ณด๊ฐ ์์ ๋ ALARM ์ฒ๋ฆฌ
+ foreach (var item in ModifiedList.ToList())
+ {
+ HandleModifyAlarm(item.Copy());
+ }
+
+ arr.ReturnToPool();
+ }
+
+ ///
+ /// AlarmManager๊ฐ ํ๊ดด๋ ๋ ํธ์ถ๋ฉ๋๋ค.
+ /// MQTT ํ์ดํ๋ผ์ธ์์ 'ALARM' ํธ๋ค๋ฌ๋ฅผ ์ ๊ฑฐํ์ฌ ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ๋ฐฉ์งํฉ๋๋ค.
+ ///
+ protected override void OnDestroy()
+ {
+ base.OnDestroy();
+ AppMain.Instance.MQTTPipeLine.Remove("ALARM");
+ }
+
+ public void HandleNewAlarm(DataObject data)
+ {
+ if (data.Id == null)
+ {
+ Debug.LogError($"New Alarm Received No data. {data}");
+ data.ReturnToPool();
+ return;
+ }
+
+ // ์์ผ๋ฉด ์๋ก ์์ฑ
+ FactoryObject? targetObject = dataManager!.FindById(data.GetString("MACHINENAME")!);
+ if (targetObject != null)
+ {
+ GameObject newUIObject = Instantiate(alarmUIPrefab, transform); // ๋งค๋์ ํ์์ ์์ฑ
+ AlarmUIController newUiController = newUIObject.GetComponent();
+ newUiController.Initialize(targetObject, data);
+
+ activeAlarmUIs.Add(data.Id!, newUiController);
+ }
+
+ }
+
+ public void HandleModifyAlarm(DataObject data)
+ {
+ if (data.Id == null)
+ {
+ Debug.LogError($"Modify Alarm Received No data. {data}");
+ data.ReturnToPool();
+ return;
+ }
// ์ด๋ฏธ ํด๋น ์ค๋น์ ์๋ UI๊ฐ ๋ ์๋์ง ํ์ธ
- if (activeAlarmUIs.TryGetValue(data.objectId, out AlarmUIController uiController))
+ if (activeAlarmUIs.TryGetValue(data.Id!, out AlarmUIController uiController))
{
// ์์ผ๋ฉด ๊ธฐ์กด UI์ ์๋ ์ ๋ณด๋ง ์ถ๊ฐ
- uiController.AddAlarm(data);
- }
- else
- {
- // ์์ผ๋ฉด ์๋ก ์์ฑ
- FactoryObject targetObject = dataManager.FindById(data.objectId);
- if (targetObject != null)
- {
- GameObject newUIObject = Instantiate(alarmUIPrefab, transform); // ๋งค๋์ ํ์์ ์์ฑ
- AlarmUIController newUiController = newUIObject.GetComponent();
- newUiController.Initialize(targetObject, data);
-
- activeAlarmUIs.Add(data.objectId, newUiController);
- }
+ uiController.UpdateAlarm(data);
}
}
- public void HandleClearedAlarm(AlarmData data)
+ public void HandleClearedAlarm(DataObject data)
{
- if (activeAlarmUIs.TryGetValue(data.objectId, out AlarmUIController uiController))
+ if (data.Id.IsNullOrEmpty())
+ {
+ Debug.LogError($"Clear Alarm Received No data. {data}");
+ data.ReturnToPool();
+ return;
+ }
+ if (activeAlarmUIs.TryGetValue(data.Id!, out AlarmUIController uiController))
{
uiController.RemoveAlarm(data);
if (uiController.GetAlarmCount() == 0)
{
- activeAlarmUIs.Remove(data.objectId);
+ activeAlarmUIs.Remove(data.Id!);
Destroy(uiController.gameObject);
}
+ data.ReturnToPool();
}
}
}
- // ์๋ ๋ฐ์ดํฐ ์ ๋ฌ์ฉ ํด๋์ค
- public class AlarmData
- {
- public string objectId;
- public string alarmId; // ๊ฐ ์๋์ ๊ณ ์ ID
- public string message;
- // ... ์ฌ๊ฐ๋, ์๊ฐ ๋ฑ ๊ธฐํ ์ ๋ณด
- }
-
}
diff --git a/Assets/Scripts/UVC/Factory/Alarm/AlarmUIController.cs b/Assets/Scripts/UVC/Factory/Alarm/AlarmUIController.cs
index 452c4318..2b7ce080 100644
--- a/Assets/Scripts/UVC/Factory/Alarm/AlarmUIController.cs
+++ b/Assets/Scripts/UVC/Factory/Alarm/AlarmUIController.cs
@@ -1,23 +1,29 @@
๏ปฟusing System.Collections.Generic;
using TMPro;
using UnityEngine;
+using UnityEngine.EventSystems;
+using UVC.Data;
using UVC.Factory.Component;
using UVC.Util;
namespace UVC.Factory.Alarm
{
- public class AlarmUIController : MonoBehaviour
+ public class AlarmUIController : MonoBehaviour, IPointerClickHandler
{
+ [Tooltip("์๋ ํด๋ฌ์คํฐ ๋ทฐ์
๋๋ค.")]
[SerializeField] private GameObject clusterView;
+ [Tooltip("์๋ ๊ฐ์๋ฅผ ํ์ํ๋ ํ
์คํธ์
๋๋ค.")]
[SerializeField] private TextMeshProUGUI alarmCountText;
+ [Tooltip("ํ์ฅ๋ ์๋ ๋ทฐ์
๋๋ค. ๊ฐ๋ณ ์๋ ์์ด์ฝ์ ํ์ํฉ๋๋ค.")]
[SerializeField] private GameObject expandedView;
+ [Tooltip("๊ฐ๋ณ ์๋ ์์ด์ฝ ํ๋ฆฌํน์
๋๋ค. ์ด ํ๋ฆฌํน์ ๊ฐ๋ณ ์๋ ์ ๋ณด๋ฅผ ํ์ํ๋ UI ์์๋ฅผ ํฌํจํด์ผ ํฉ๋๋ค.")]
[SerializeField] private GameObject singleAlarmIconPrefab; // ๊ฐ๋ณ ์๋ ์์ด์ฝ
private Transform targetObject;
- private List alarms = new List();
+ private List alarms = new List();
private bool isExpanded = false;
- public void Initialize(FactoryObject target, AlarmData initialAlarm)
+ public void Initialize(FactoryObject target, DataObject initialAlarm)
{
this.targetObject = target.transform;
AddAlarm(initialAlarm);
@@ -30,13 +36,32 @@ namespace UVC.Factory.Alarm
transform.rotation = Camera.main.transform.rotation;
}
- public void AddAlarm(AlarmData alarm)
+ public void AddAlarm(DataObject alarm)
{
alarms.Add(alarm);
UpdateView();
}
- public void RemoveAlarm(AlarmData alarm)
+ public void UpdateAlarm(DataObject alarm)
+ {
+ // ์ค์ ๋ก๋ alarmId๋ก ์ฐพ์์ ์
๋ฐ์ดํธํด์ผ ํจ
+ int index = alarms.FindIndex(a => a.Id == alarm.Id);
+ if (index >= 0)
+ {
+ foreach (var key in alarm.Keys)
+ {
+ alarms[index][key] = alarm[key]; // ๊ธฐ์กด ์๋ ๋ฐ์ดํฐ ์
๋ฐ์ดํธ
+ }
+ alarm.ReturnToPool();
+ UpdateView();
+ }
+ else
+ {
+ Debug.LogWarning($"Alarm with ID {alarm.Id} not found for update.");
+ }
+ }
+
+ public void RemoveAlarm(DataObject alarm)
{
// ์ค์ ๋ก๋ alarmId๋ก ์ฐพ์์ ์ง์์ผ ํจ
alarms.Remove(alarm);
@@ -123,5 +148,10 @@ namespace UVC.Factory.Alarm
}
public int GetAlarmCount() => alarms.Count;
+
+ public void OnPointerClick(PointerEventData eventData)
+ {
+ OnPointerClick();
+ }
}
}
diff --git a/Assets/Scripts/UVC/Factory/Alarm/SingleAlarmIcon.cs b/Assets/Scripts/UVC/Factory/Alarm/SingleAlarmIcon.cs
index 8734cce3..9173fd3d 100644
--- a/Assets/Scripts/UVC/Factory/Alarm/SingleAlarmIcon.cs
+++ b/Assets/Scripts/UVC/Factory/Alarm/SingleAlarmIcon.cs
@@ -1,25 +1,56 @@
-๏ปฟusing UnityEngine;
+๏ปฟusing TMPro;
+using UnityEngine;
+using UVC.Data;
using UVC.Util;
namespace UVC.Factory.Alarm
{
public class SingleAlarmIcon : MonoBehaviour
{
- private AlarmData myAlarmData;
+
+ [Tooltip("์๋ ๋ด์ฉ์ ํ์ํ๋ ํ
์คํธ์
๋๋ค.")]
+ [SerializeField] private TextMeshProUGUI text;
+
+ private DataObject data;
private Transform equipmentTransform;
- public void SetData(AlarmData data, Transform equipment)
+ public void SetData(DataObject newData, Transform equipment)
{
- myAlarmData = data;
+ if (data == null)
+ {
+ data = newData;
+ }
+ else
+ {
+ foreach (var keyValue in newData)
+ {
+ if (data.ContainsKey(keyValue.Key))
+ {
+ data[keyValue.Key] = keyValue.Value;
+ }
+ }
+ }
+
equipmentTransform = equipment;
- // ์์ด์ฝ ๋ชจ์์ด๋ ์์ ์๋ ์ฌ๊ฐ๋์ ๋ฐ๋ผ ๋ณ๊ฒฝ ๊ฐ๋ฅ
+
+ if (text != null)
+ {
+ string combinedString = string.Empty;
+ foreach (var kvp in data)
+ {
+ // ํ๊ทธ๋ฅผ ์ฌ์ฉํ์ฌ ์ค๋ฐ๊ฟ ์์๋ ์ ๋ ฌ์ด ์ ์ง๋๋๋ก ํฉ๋๋ค.
+ combinedString += $"{kvp.Key}{kvp.Value ?? "null"}\n";
+ }
+ combinedString = combinedString.TrimEnd('\n'); // ๋ง์ง๋ง ์ค๋ฐ๊ฟ ์ ๊ฑฐ
+ text.text = combinedString;
+ }
}
public void OnPointerClick()
{
// ํด๋ฆญ ์ ํด๋น ์ค๋น๋ก ์นด๋ฉ๋ผ ํฌ์ปค์ค
CameraController.Instance.FocusOnTarget(equipmentTransform, 3.0f);
- Debug.Log($"์๋ [{myAlarmData.message}]์ด ๋ฐ์ํ ์ค๋น๋ก ์ด๋ํฉ๋๋ค.");
+ Debug.Log($"์๋ [{data.GetString("MESSAGE")}]์ด ๋ฐ์ํ ์ค๋น๋ก ์ด๋ํฉ๋๋ค.");
// ์ฌ๊ธฐ์ ์๋ ์์ธ์ ๋ณด ํจ๋์ ๋์๋ ์ข์
}
}
diff --git a/Assets/Scripts/UVC/Factory/Component/AGV.cs b/Assets/Scripts/UVC/Factory/Component/AGV.cs
index d6e359ae..2c193cc0 100644
--- a/Assets/Scripts/UVC/Factory/Component/AGV.cs
+++ b/Assets/Scripts/UVC/Factory/Component/AGV.cs
@@ -104,46 +104,63 @@ namespace UVC.Factory.Component
// ์ฒ์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๋ ๊ฒฝ์ฐ, ๋ฐ์ ๋ฐ์ดํฐ๋ก ์ฆ์ ์์น๋ฅผ ์ค์ ํฉ๋๋ค.
if (data == null)
{
- float x = newData.GetFloat("X") * scaleFactor;
- float y = newData.GetFloat("Y") * scaleFactor;
- Quaternion rotation = Quaternion.Euler(0, newData.GetFloat("DEGREE"), 0);
+ float x = newData.GetFloat("X").Value * scaleFactor;
+ float y = newData.GetFloat("Y").Value * scaleFactor;
+ Quaternion rotation = Quaternion.Euler(0, newData.GetFloat("DEGREE").Value, 0);
transform.position = new Vector3(x, 0, y);
transform.rotation = rotation;
}
else // ์ดํ ์
๋ฐ์ดํธ์ ๊ฒฝ์ฐ
{
- // ์ ๋ฐ์ดํฐ๋ก๋ถํฐ ๋ชฉํ ์์น์ ํ์ ๊ฐ์ ๊ณ์ฐํฉ๋๋ค.
- float x = data.GetFloat("X") * scaleFactor;
- float y = data.GetFloat("Y") * scaleFactor;
- Quaternion rotation = Quaternion.Euler(0, data.GetFloat("DEGREE"), 0);
+ bool isTeleport = false;
- float newX = (newData.ContainsKey("X") ? newData.GetFloat("X") : data.GetFloat("X")) * scaleFactor;
- float newY = (newData.ContainsKey("Y") ? newData.GetFloat("Y") : data.GetFloat("Y")) * scaleFactor;
- float newDegree = (newData.ContainsKey("DEGREE") ? newData.GetFloat("DEGREE") : data.GetFloat("DEGREE"));
- Quaternion newRotation = Quaternion.Euler(0, newDegree, 0);
- Vector3 newTargetPosition = new Vector3(x, transform.position.y, y);
- Quaternion newTargetRotation = rotation;
-
- if (x != newX || y != newY) newTargetPosition = new Vector3(newX, transform.position.y, newY);
- if (rotation != newRotation) newTargetRotation = newRotation;
-
- // ํ์ฌ ์์น์ ์๋ก์ด ๋ชฉํ ์์น ์ฌ์ด์ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ์ฐํฉ๋๋ค.
- float distanceToTarget = Vector3.Distance(transform.position, newTargetPosition);
-
- // ๊ฑฐ๋ฆฌ๊ฐ ์ค์ ๋ ์๊ณ๊ฐ์ ์ด๊ณผํ๋ฉด, ๋ณด๊ฐ์ ๊ฑด๋๋ฐ๊ณ ์ฆ์ ์์น/ํ์ ์ ์ค์ ํฉ๋๋ค.
- if (distanceToTarget > teleportDistanceThreshold)
+ float? newX = newData.GetFloat("X");
+ float? newY = newData.GetFloat("Y");
+ if (newX.HasValue || newY.HasValue)
{
- transform.position = newTargetPosition;
- transform.rotation = newTargetRotation;
+ float x = data.GetFloat("X").Value;
+ float y = data.GetFloat("Y").Value;
+
+ Vector3 newTargetPosition = transform.position;
+ if (newX.HasValue && x != newX) newTargetPosition.x = newX.Value * scaleFactor;
+ if (newY.HasValue && y != newY) newTargetPosition.z = newY.Value * scaleFactor;
+
+ if (newTargetPosition != transform.position)
+ {
+
+ // ํ์ฌ ์์น์ ์๋ก์ด ๋ชฉํ ์์น ์ฌ์ด์ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ์ฐํฉ๋๋ค.
+ float distanceToTarget = Vector3.Distance(transform.position, newTargetPosition);
+
+ // ๊ฑฐ๋ฆฌ๊ฐ ์ค์ ๋ ์๊ณ๊ฐ์ ์ด๊ณผํ๋ฉด, ๋ณด๊ฐ์ ๊ฑด๋๋ฐ๊ณ ์ฆ์ ์์น์ ์ค์ ํฉ๋๋ค.
+ if (distanceToTarget > teleportDistanceThreshold)
+ {
+ transform.position = newTargetPosition;
+ isTeleport = true; // ์๊ฐ์ด๋์ด ๋ฐ์ํ์์ ํ์ํฉ๋๋ค.
+ }
+
+ // ์๋ก์ด ๋ชฉํ ์ง์ ์ ์ค์ ํฉ๋๋ค.
+ // (์๊ฐ์ด๋์ ํ๋ ์ ํ๋ , ๋ค์ ํ๋ ์๋ถํฐ์ ๋ณด๊ฐ์ ์ํด ๋ชฉํ ์ง์ ์ ํญ์ ๊ฐฑ์ ๋์ด์ผ ํฉ๋๋ค.)
+ this.targetPosition = newTargetPosition;
+ }
}
- // ์๋ก์ด ๋ชฉํ ์ง์ ์ ์ค์ ํฉ๋๋ค.
- // (์๊ฐ์ด๋์ ํ๋ ์ ํ๋ , ๋ค์ ํ๋ ์๋ถํฐ์ ๋ณด๊ฐ์ ์ํด ๋ชฉํ ์ง์ ์ ํญ์ ๊ฐฑ์ ๋์ด์ผ ํฉ๋๋ค.)
- this.targetPosition = newTargetPosition;
- this.targetRotation = newTargetRotation;
+ float? newDegree = newData.GetFloat("DEGREE");
+ if(newDegree.HasValue)
+ {
+ if (data.GetFloat("DEGREE").Value != newDegree.Value)
+ {
+ Quaternion newTargetRotation = Quaternion.Euler(0, newDegree.Value, 0);
+
+ // ๊ฑฐ๋ฆฌ๊ฐ ์ค์ ๋ ์๊ณ๊ฐ์ ์ด๊ณผํ๋ฉด, ๋ณด๊ฐ์ ๊ฑด๋๋ฐ๊ณ ์ฆ์ ์์น/ํ์ ์ ์ค์ ํฉ๋๋ค
+ if (isTeleport) transform.rotation = newTargetRotation;
+
+ // ์๋ก์ด ๋ชฉํ ์ง์ ์ ์ค์ ํฉ๋๋ค.
+ // (์๊ฐ์ด๋์ ํ๋ ์ ํ๋ , ๋ค์ ํ๋ ์๋ถํฐ์ ๋ณด๊ฐ์ ์ํด ๋ชฉํ ์ง์ ์ ํญ์ ๊ฐฑ์ ๋์ด์ผ ํฉ๋๋ค.)
+ this.targetRotation = newTargetRotation;
+ }
+ }
- newData.ReturnToPool(); // ์ฌ์ฉ์ด ๋๋ ๋ฐ์ดํฐ ๊ฐ์ฒด๋ฅผ ํ์ ๋ฐํํฉ๋๋ค.
}
}
diff --git a/Assets/Scripts/UVC/Factory/Component/AGVManager.cs b/Assets/Scripts/UVC/Factory/Component/AGVManager.cs
index 3cd77bfb..ed73e4ba 100644
--- a/Assets/Scripts/UVC/Factory/Component/AGVManager.cs
+++ b/Assets/Scripts/UVC/Factory/Component/AGVManager.cs
@@ -80,7 +80,21 @@ namespace UVC.Factory.Component
{
private readonly string prefabPath = "Prefabs/SampleProject/Factory/AGV";
- private MonoBehaviourPool? agvPool;
+ private GameObjectPool? agvPool;
+
+ public GameObjectPool AGVPool
+ {
+ get
+ {
+ if (agvPool == null)
+ {
+ Debug.LogError("AGVPool is not initialized. Please call InitializePoolAsync first.");
+ }
+ return agvPool!;
+ }
+ }
+
+ private bool created = false;
///
/// AGVManager์ ์ด๊ธฐํ ๋ฉ์๋์
๋๋ค.
@@ -150,7 +164,7 @@ namespace UVC.Factory.Component
Debug.LogError($"Prefab not found at path: {prefabPath}");
return;
}
- agvPool = new MonoBehaviourPool(prefab, transform);
+ agvPool = new GameObjectPool(prefab, transform);
}
///
@@ -176,7 +190,7 @@ namespace UVC.Factory.Component
var RemovedItems = arr.RemovedItems;
var ModifiedList = arr.ModifiedList;
- Debug.Log($"AGVManager received data: Added={AddedItems.Count}, Removed={RemovedItems.Count}, Modified={ModifiedList.Count}");
+ //Debug.Log($"AGVManager received data: Added={AddedItems.Count}, Removed={RemovedItems.Count}, Modified={ModifiedList.Count}");
// ์๋ก ์ถ๊ฐ๋ AGV ์ฒ๋ฆฌ
foreach (var item in AddedItems.ToList())
@@ -194,7 +208,7 @@ namespace UVC.Factory.Component
"",
item.GetString("MODE")
);
- agv.UpdateData(item.Clone());
+ agv.UpdateData(item.Copy());
}
// ์ ๊ฑฐ๋ AGV ์ฒ๋ฆฌ
@@ -211,16 +225,22 @@ namespace UVC.Factory.Component
// ์ ๋ณด๊ฐ ์์ ๋ AGV ์ฒ๋ฆฌ
foreach (var item in ModifiedList.ToList())
{
- Debug.Log($"AGVManager modified data: {item.ToString()}");
+ if(item.Id == "HFF09CNA8047") Debug.Log($"AGVManager modified data: {item.ToString()}");
string vhlName = item.GetString("VHL_NAME")!;
AGV? agv = agvPool.FindActiveItem(vhlName);
if (agv != null)
{
- agv.UpdateData(item.Clone());
+ agv.UpdateData(item.Copy());
}
}
arr.ReturnToPool();
+ if(created == false)
+ {
+ created = true;
+ // ์ฌ์ด ์ฒ์ ์ด๊ธฐํ๋ ๋ AGVManager๊ฐ ์์ฑ๋์์์ ์๋ฆฝ๋๋ค.
+ SceneMain.Instance.OnAGVManagerCreated();
+ }
}
///
diff --git a/Assets/Scripts/UVC/Factory/Component/FactoryObject.cs b/Assets/Scripts/UVC/Factory/Component/FactoryObject.cs
index 30058035..971d61e5 100644
--- a/Assets/Scripts/UVC/Factory/Component/FactoryObject.cs
+++ b/Assets/Scripts/UVC/Factory/Component/FactoryObject.cs
@@ -110,8 +110,11 @@ namespace UVC.Factory.Component
/// }
///
///
- public abstract class FactoryObject : InteractiveObject
+ public abstract class FactoryObject : MonoBehaviour, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler
{
+ [Tooltip("3D ๋ชจ๋ธ ๊ฐ์ฒด")]
+ public InteractiveObject? modelObject;
+
protected FactoryObjectInfo? info;
///
@@ -149,9 +152,30 @@ namespace UVC.Factory.Component
}
}
-
- private void OnDestroy()
+ protected virtual void Awake()
{
+ // ์ด๊ธฐํ ์์
์ ์ํํฉ๋๋ค.
+ if (modelObject == null)
+ {
+ Debug.LogError("FactoryObject requires an InteractiveObject component.");
+ }
+ else
+ {
+ modelObject.OnPointerClickHandler += OnPointerClick;
+ modelObject.OnPointerEnterHandler += OnPointerEnter;
+ modelObject.OnPointerExitHandler += OnPointerExit;
+ }
+ }
+
+
+ protected virtual void OnDestroy()
+ {
+ if (modelObject != null)
+ {
+ modelObject.OnPointerClickHandler -= OnPointerClick;
+ modelObject.OnPointerEnterHandler -= OnPointerEnter;
+ modelObject.OnPointerExitHandler -= OnPointerExit;
+ }
FactoryObjectManager.Instance.UnregisterFactoryObject(Info!);
}
@@ -165,7 +189,7 @@ namespace UVC.Factory.Component
/// `DataOrderedMask`๊ฐ ์ค์ ๋์ด ์์ผ๋ฉด ํด๋น ์์๋๋ก, ๊ทธ๋ ์ง ์์ผ๋ฉด ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ํ์ํฉ๋๋ค.
///
/// ํฌ์ธํฐ ํด๋ฆญ๊ณผ ๊ด๋ จ๋ ์ด๋ฒคํธ ๋ฐ์ดํฐ์
๋๋ค.
- public override void OnPointerClick(PointerEventData eventData)
+ public void OnPointerClick(PointerEventData eventData)
{
if (data != null && data.Count > 0)
{
@@ -190,18 +214,28 @@ namespace UVC.Factory.Component
}
}
+ ///
+ /// ํฌ์ธํฐ๊ฐ ์ด ๊ฐ์ฒด ์๋ก ๋ค์ด์์ ๋ ํธ์ถ๋ฉ๋๋ค. ํ์ด๋ผ์ดํธ ํจ๊ณผ ๋ฑ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
+ ///
+ /// ํฌ์ธํฐ ์ด๋ฒคํธ์ ๊ด๋ จ๋ ๋ฐ์ดํฐ์
๋๋ค.
+ public void OnPointerEnter(PointerEventData eventData) { }
+
+ ///
+ /// ํฌ์ธํฐ๊ฐ ์ด ๊ฐ์ฒด์์ ๋ฒ์ด๋ฌ์ ๋ ํธ์ถ๋ฉ๋๋ค.
+ ///
+ /// ํฌ์ธํฐ ์ด๋ฒคํธ์ ๊ด๋ จ๋ ๋ฐ์ดํฐ์
๋๋ค.
+ public void OnPointerExit(PointerEventData eventData) { }
+
///
/// ์ธ๋ถ๋ก๋ถํฐ ๋ฐ์ ์๋ก์ด ๋ฐ์ดํฐ๋ก ๊ฐ์ฒด์ ์ํ๋ฅผ ์
๋ฐ์ดํธํฉ๋๋ค.
/// ์ด ๋ฉ์๋๋ ๋ด๋ถ์ ์ผ๋ก `ProcessData`๋ฅผ ํธ์ถํ์ฌ ์ค์ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๋ก์ง์ ์ํํฉ๋๋ค.
/// MQTTPipeLineInfo.updatedDataOnly๊ฐ true์ธ ๊ฒฝ์ฐ, ๋ฐ์ดํฐ๊ฐ ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ์๋ง ํธ์ถ๋ฉ๋๋ค.
///
/// ์
๋ฐ์ดํธํ ์๋ก์ด ๋ฐ์ดํฐ๊ฐ ํฌํจ๋ IDataObject ๊ฐ์ฒด์
๋๋ค.
- public void UpdateData(IDataObject? newData)
+ public void UpdateData(DataObject newData)
{
if(newData == null) return;
- DataObject? dataObject = newData as DataObject;
- if (dataObject == null || dataObject.Count == 0) return;
- ProcessData(dataObject);
+ ProcessData(newData);
}
///
diff --git a/Assets/Scripts/UVC/Factory/Component/FactoryObjectManager.cs b/Assets/Scripts/UVC/Factory/Component/FactoryObjectManager.cs
index e3a9808d..ec9ed463 100644
--- a/Assets/Scripts/UVC/Factory/Component/FactoryObjectManager.cs
+++ b/Assets/Scripts/UVC/Factory/Component/FactoryObjectManager.cs
@@ -148,7 +148,7 @@ namespace UVC.Factory.Component
/// ์ฐพ๊ณ ์ ํ๋ ๊ฐ์ฒด์ ID์
๋๋ค.
/// ์ฒ์์ผ๋ก ๋ฐ๊ฒฌ๋ ์ผ์นํ๋ FactoryObject. ์์ผ๋ฉด null์ ๋ฐํํฉ๋๋ค.
public FactoryObject? FindById(string id)
- {
+ {
foreach (var kvp in FactoryObjects)
{
if (kvp.Key.Id.Equals(id, StringComparison.OrdinalIgnoreCase))
diff --git a/Assets/Scripts/UVC/Object3d/InteractiveObject.cs b/Assets/Scripts/UVC/Object3d/InteractiveObject.cs
index c4aa8341..5dfa7f96 100644
--- a/Assets/Scripts/UVC/Object3d/InteractiveObject.cs
+++ b/Assets/Scripts/UVC/Object3d/InteractiveObject.cs
@@ -1,4 +1,6 @@
-๏ปฟusing UnityEngine;
+๏ปฟusing System;
+using Unity.VisualScripting;
+using UnityEngine;
using UnityEngine.EventSystems;
namespace UVC.Object3d
@@ -14,24 +16,37 @@ namespace UVC.Object3d
/// 3. ๋ฉ์ธ ์นด๋ฉ๋ผ์ ์ปดํฌ๋ํธ๊ฐ ๋ถ์ฐฉ๋์ด ์์ด์ผ ํฉ๋๋ค.
///
[RequireComponent(typeof(Collider))]
- public abstract class InteractiveObject : MonoBehaviour, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler
+ public class InteractiveObject : MonoBehaviour, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler
{
+ public Action OnPointerClickHandler;
+ public Action OnPointerEnterHandler;
+ public Action OnPointerExitHandler;
+
///
/// ํฌ์ธํฐ๋ก ์ด ๊ฐ์ฒด๋ฅผ ํด๋ฆญํ์ ๋ ํธ์ถ๋ฉ๋๋ค.
///
/// ํด๋ฆญ ์ด๋ฒคํธ์ ๊ด๋ จ๋ ๋ฐ์ดํฐ์
๋๋ค.
- public virtual void OnPointerClick(PointerEventData eventData) {}
+ public virtual void OnPointerClick(PointerEventData eventData)
+ {
+ OnPointerClickHandler?.Invoke(eventData);
+ }
///
/// ํฌ์ธํฐ๊ฐ ์ด ๊ฐ์ฒด ์๋ก ๋ค์ด์์ ๋ ํธ์ถ๋ฉ๋๋ค. ํ์ด๋ผ์ดํธ ํจ๊ณผ ๋ฑ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
///
/// ํฌ์ธํฐ ์ด๋ฒคํธ์ ๊ด๋ จ๋ ๋ฐ์ดํฐ์
๋๋ค.
- public virtual void OnPointerEnter(PointerEventData eventData) {}
+ public virtual void OnPointerEnter(PointerEventData eventData)
+ {
+ OnPointerEnterHandler?.Invoke(eventData);
+ }
///
/// ํฌ์ธํฐ๊ฐ ์ด ๊ฐ์ฒด์์ ๋ฒ์ด๋ฌ์ ๋ ํธ์ถ๋ฉ๋๋ค.
///
/// ํฌ์ธํฐ ์ด๋ฒคํธ์ ๊ด๋ จ๋ ๋ฐ์ดํฐ์
๋๋ค.
- public virtual void OnPointerExit(PointerEventData eventData) {}
+ public virtual void OnPointerExit(PointerEventData eventData)
+ {
+ OnPointerExitHandler?.Invoke(eventData);
+ }
}
}
diff --git a/Assets/Scripts/UVC/Pool/MonoBehaviourPool.cs b/Assets/Scripts/UVC/Pool/GameObjectPool.cs
similarity index 83%
rename from Assets/Scripts/UVC/Pool/MonoBehaviourPool.cs
rename to Assets/Scripts/UVC/Pool/GameObjectPool.cs
index 507a49bc..d9c17ce0 100644
--- a/Assets/Scripts/UVC/Pool/MonoBehaviourPool.cs
+++ b/Assets/Scripts/UVC/Pool/GameObjectPool.cs
@@ -17,12 +17,12 @@ namespace UVC.Pool
/// {
/// public GameObject bulletPrefab;
/// public Transform bulletContainer;
- /// private MonoBehaviourPool<Bullet> _bulletPool;
+ /// private GameObjectPool _bulletPool;
///
/// void Start()
/// {
/// // ์ด์ ํ๋ฆฌํน๊ณผ ๋ถ๋ชจ ์ปจํ
์ด๋๋ฅผ ์ฌ์ฉํ์ฌ ํ์ ์ด๊ธฐํํฉ๋๋ค.
- /// _bulletPool = new MonoBehaviourPool<Bullet>(bulletPrefab, bulletContainer);
+ /// _bulletPool = new GameObjectPool(bulletPrefab, bulletContainer);
/// }
///
/// void SpawnBullet()
@@ -42,7 +42,7 @@ namespace UVC.Pool
///
///
/// ํ๋งํ MonoBehaviour ํ์
์
๋๋ค.
- public class MonoBehaviourPool where T : MonoBehaviour
+ public class GameObjectPool where T : MonoBehaviour
{
///
/// Resources ํด๋์ ์๋ ํ๋ฆฌํน์ ๊ฒฝ๋ก์
๋๋ค.
@@ -88,13 +88,19 @@ namespace UVC.Pool
///
public Transform? RecycledItemContainer { get { return _recycledItemContainer; } }
+ // --- ํต๊ณ์ฉ ํ๋ ---
+ private int _inUseCount = 0;
+ private int _peakUsage = 0;
+ private int _poolMisses = 0;
+ private readonly object _statsLock = new object();
+
///
/// GameObject ํ๋ฆฌํน์ ์ฌ์ฉํ์ฌ ํ์ ์ด๊ธฐํํฉ๋๋ค.
///
/// ํ๋งํ ์ค๋ธ์ ํธ์ ์๋ณธ ํ๋ฆฌํน์
๋๋ค.
/// ํ์ฑํ๋ ์ค๋ธ์ ํธ๊ฐ ์์นํ ๋ถ๋ชจ Transform์
๋๋ค.
/// ๋นํ์ฑํ๋ ์ค๋ธ์ ํธ๊ฐ ์์นํ ๋ถ๋ชจ Transform์
๋๋ค. ์ง์ ํ์ง ์์ผ๋ฉด activeItemContainer๊ฐ ์ฌ์ฉ๋ฉ๋๋ค.
- public MonoBehaviourPool(GameObject originalPrefab, Transform activeItemContainer, Transform recycledItemContainer = null)
+ public GameObjectPool(GameObject originalPrefab, Transform activeItemContainer, Transform recycledItemContainer = null)
{
_originalPrefab = originalPrefab;
_activeItemContainer = activeItemContainer;
@@ -109,7 +115,7 @@ namespace UVC.Pool
/// Resources ํด๋ ๊ธฐ์ค์ ํ๋ฆฌํน ๊ฒฝ๋ก์
๋๋ค.
/// ํ์ฑํ๋ ์ค๋ธ์ ํธ๊ฐ ์์นํ ๋ถ๋ชจ Transform์
๋๋ค.
/// ๋นํ์ฑํ๋ ์ค๋ธ์ ํธ๊ฐ ์์นํ ๋ถ๋ชจ Transform์
๋๋ค. ์ง์ ํ์ง ์์ผ๋ฉด activeItemContainer๊ฐ ์ฌ์ฉ๋ฉ๋๋ค.
- public MonoBehaviourPool(string prefabsPath, Transform activeItemContainer, Transform recycledItemContainer)
+ public GameObjectPool(string prefabsPath, Transform activeItemContainer, Transform recycledItemContainer)
{
_prefabsPath = prefabsPath;
_originalPrefab = Resources.Load(prefabsPath);
@@ -133,6 +139,16 @@ namespace UVC.Pool
}
T? item = null;
+
+ lock (_statsLock)
+ {
+ _inUseCount++;
+ if (_inUseCount > _peakUsage)
+ {
+ _peakUsage = _inUseCount;
+ }
+ }
+
if (_recycledItems.Count > 0)
{
item = _recycledItems[0];
@@ -140,6 +156,11 @@ namespace UVC.Pool
}
else
{
+ lock (_statsLock)
+ {
+ _poolMisses++;
+ }
+
GameObject go = UnityEngine.Object.Instantiate(_originalPrefab);
item = go.GetComponent();
}
@@ -173,6 +194,11 @@ namespace UVC.Pool
return; // ํค์ ํด๋นํ๋ ์์ดํ
์ด ์์ผ๋ฉด ๋ฐํ
}
+ lock (_statsLock)
+ {
+ _inUseCount--;
+ }
+
_activeItems.Remove(key);
_recycledItems.Add(item);
@@ -224,5 +250,26 @@ namespace UVC.Pool
}
_recycledItems.Clear();
}
+
+ ///
+ /// ํ์ ํ์ฌ ์ฑ๋ฅ ํต๊ณ๋ฅผ ๋ฌธ์์ด๋ก ๋ฐํํฉ๋๋ค.
+ ///
+ /// ํ ํต๊ณ (์ต๋ ์ฌ์ฉ๋, ํ์ฌ ์ฌ์ฉ๋, ํ ๋น์ด์์ ๋ ์์ฑ ํ์, ํ์ฌ ํ ํฌ๊ธฐ)
+ public string GetStats()
+ {
+ return $"์ต๋ ์ฌ์ฉ๋: {_peakUsage}, ํ์ฌ ์ฌ์ฉ๋: {_inUseCount}, ํ ๋น์ด์์ ๋ ์์ฑ ํ์: {_poolMisses}, ํ์ฌ ํ ํฌ๊ธฐ: {_recycledItems.Count}";
+ }
+
+ ///
+ /// ํ ํต๊ณ๋ฅผ ์ด๊ธฐํํฉ๋๋ค.
+ ///
+ public void ResetStats()
+ {
+ lock (_statsLock)
+ {
+ _peakUsage = 0;
+ _poolMisses = 0;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/Assets/Scripts/UVC/Pool/GameObjectPool.cs.meta b/Assets/Scripts/UVC/Pool/GameObjectPool.cs.meta
new file mode 100644
index 00000000..17096f42
--- /dev/null
+++ b/Assets/Scripts/UVC/Pool/GameObjectPool.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: e163d2d37fef9bd49acd0f3fa5b5d2dc
\ No newline at end of file
diff --git a/Assets/Scripts/UVC/Pool/MonoBehaviourPool.cs.meta b/Assets/Scripts/UVC/Pool/MonoBehaviourPool.cs.meta
deleted file mode 100644
index e6061515..00000000
--- a/Assets/Scripts/UVC/Pool/MonoBehaviourPool.cs.meta
+++ /dev/null
@@ -1,2 +0,0 @@
-fileFormatVersion: 2
-guid: e9be41afc37616649924d7190be6215a
\ No newline at end of file
diff --git a/Assets/Scripts/UVC/UI/Info/InfoWindow.cs b/Assets/Scripts/UVC/UI/Info/InfoWindow.cs
index 63907495..b3ba6658 100644
--- a/Assets/Scripts/UVC/UI/Info/InfoWindow.cs
+++ b/Assets/Scripts/UVC/UI/Info/InfoWindow.cs
@@ -1,5 +1,6 @@
๏ปฟ#nullable enable
+using System;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
@@ -19,10 +20,14 @@ namespace UVC.UI.Info
[SerializeField]
private TextMeshProUGUI text;
- [Tooltip("์ ๋ณด ์ฐฝ์ ๋ซ์ ๋ฒํผ")]
+ [Tooltip("์ ๋ณด ์ฐฝ์ ๋ซ๋ ๋ฒํผ")]
[SerializeField]
private Button closeButton;
+ [Tooltip("์ ๋ณด ์ฐฝ์ ๋ด์ฉ์ ํด๋ฆฝ๋ณด๋์ ๋ณต์ฌํ ๋ฒํผ")]
+ [SerializeField]
+ private Button copyButton;
+
[Tooltip("UI๊ฐ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌ์ง ์๋๋ก ํ ์๋ ์ขํ๊ณ ์คํ์
")]
[SerializeField]
private Vector2 screenOffset = new Vector2(10f, 10f);
@@ -34,6 +39,7 @@ namespace UVC.UI.Info
// ์ ๋ณด ์ฐฝ์ด ๋ฐ๋ผ๋ค๋ 3D ๊ฐ์ฒด์ Transform
private Transform? target;
+ private string message = string.Empty;
///
/// ์ ๋ณด ์ฐฝ์ด ํ์ฌ ํ๋ฉด์ ํ์๋๊ณ ์๋์ง ์ฌ๋ถ๋ฅผ ๋ฐํํฉ๋๋ค.
@@ -54,6 +60,12 @@ namespace UVC.UI.Info
closeButton.onClick.AddListener(Hide);
}
+ if (copyButton != null)
+ {
+ copyButton.onClick.AddListener(CopyToClipboard);
+ }
+
+
// ์ฒ์์๋ ์ ๋ณด ์ฐฝ์ ์จ๊น๋๋ค.
if (gameObject.activeSelf)
{
@@ -61,6 +73,15 @@ namespace UVC.UI.Info
}
}
+ private void CopyToClipboard()
+ {
+ // ํด๋ฆฝ๋ณด๋์ ํ์ฌ ๋ฉ์์ง๋ฅผ ๋ณต์ฌํฉ๋๋ค.
+ if (!string.IsNullOrEmpty(message))
+ {
+ GUIUtility.systemCopyBuffer = message;
+ }
+ }
+
private void LateUpdate()
{
// target์ด ์ค์ ๋์ด ์๊ณ ํ์ฑํ ์ํ์ผ ๋๋ง ์์น์ ๋ฐฉํฅ์ ์
๋ฐ์ดํธํฉ๋๋ค.
@@ -158,6 +179,7 @@ namespace UVC.UI.Info
}
combinedString = combinedString.TrimEnd('\n'); // ๋ง์ง๋ง ์ค๋ฐ๊ฟ ์ ๊ฑฐ
text.text = combinedString;
+ message = combinedString;
}
// size๋ฅผ text์ ๋ง๊ฒ ์กฐ์ ํฉ๋๋ค.
RectTransform? rect = GetComponent();
diff --git a/Assets/Scripts/UVC/UI/Menu/TopMenuController.cs b/Assets/Scripts/UVC/UI/Menu/TopMenuController.cs
index 03b0f908..ad837bac 100644
--- a/Assets/Scripts/UVC/UI/Menu/TopMenuController.cs
+++ b/Assets/Scripts/UVC/UI/Menu/TopMenuController.cs
@@ -1,6 +1,8 @@
๏ปฟusing System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
+using UVC.Data;
+using UVC.Factory.Component;
using UVC.Locale;
using UVC.Log;
using UVC.UI.Commands;
@@ -215,17 +217,12 @@ namespace UVC.UI.Menu
new MenuItemData("file_exit", "menu_file_exit", new QuitApplicationCommand()) // ์ ํ๋ฆฌ์ผ์ด์
์ข
๋ฃ ๋ช
๋ น ์ฐ๊ฒฐ
}));
- // "ํธ์ง" ๋ฉ๋ด ๋ฐ ํ์ ๋ฉ๋ด๋ค ์ ์
- model.MenuItems.Add(new MenuItemData("edit", "menu_edit", subMenuItems: new List
+ // pool ๋ก๊ทธ
+ model.MenuItems.Add(new MenuItemData("log", "Log", subMenuItems: new List
{
- new MenuItemData("edit_undo", "menu_edit_undo", new DebugLogCommand("์คํ ์ทจ์ ์ ํ๋จ (Command ์คํ)")),
- new MenuItemData("edit_redo", "menu_edit_redo", new DebugLogCommand("๋ค์ ์คํ ์ ํ๋จ (Command ์คํ)")),
- MenuItemData.CreateSeparator("edit_sep1"), // ๊ตฌ๋ถ์
- new MenuItemData("file_save", "menu_file_save", command: new DebugLogCommand("์ ์ฅ ์ ํ๋จ (Command ์คํ)") , subMenuItems: new List
- {
- new MenuItemData("file_save_as", "menu_file_save_as", new DebugLogCommand("๋ค๋ฅธ ์ด๋ฆ์ผ๋ก ์ ์ฅ ์ ํ๋จ (Command ์คํ)"))
- }),
- new MenuItemData("preferences", "menu_preferences", new DebugLogCommand("ํ๊ฒฝ์ค์ ์ ํ๋จ (Command ์คํ)"))
+ new MenuItemData("dataArray", "DataArray", new ActionCommand(() => Debug.Log($"DataArrayPool stats: {DataArrayPool.GetStats()}"))),
+ new MenuItemData("dataObject", "DataObjet", new ActionCommand(() => Debug.Log($"DataObjectPool stats: {DataObjectPool.GetStats()}"))),
+ new MenuItemData("agv", "AGVPool", new ActionCommand(() => Debug.Log($"AGVPool stats: {AGVManager.Instance.AGVPool.GetStats()}"))),
}));
model.MenuItems.Add(new MenuItemData("modal", "๋ชจ๋ฌ", subMenuItems: new List
{
diff --git a/Packages/manifest.json b/Packages/manifest.json
index 2a5ed8b9..669a5e25 100644
--- a/Packages/manifest.json
+++ b/Packages/manifest.json
@@ -2,6 +2,7 @@
"dependencies": {
"com.cysharp.unitask": "https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask",
"com.holyshovelsoft.opensource.log4uni": "https://github.com/HolyShovelSoft/log4uni.git#upm",
+ "com.unity.2d.sprite": "1.0.0",
"com.unity.ai.navigation": "2.0.5",
"com.unity.collab-proxy": "2.8.2",
"com.unity.ide.rider": "3.0.31",
diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json
index 56f84e42..6de8da8f 100644
--- a/Packages/packages-lock.json
+++ b/Packages/packages-lock.json
@@ -14,6 +14,12 @@
"dependencies": {},
"hash": "39314556b525b9a5a4ea47b7166788422d1975e1"
},
+ "com.unity.2d.sprite": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {}
+ },
"com.unity.ai.navigation": {
"version": "2.0.5",
"depth": 0,