diff --git a/Assets/Resources/Prefabs/UI/Factory.meta b/Assets/Resources/Prefabs/UI/Factory.meta new file mode 100644 index 00000000..7a82a968 --- /dev/null +++ b/Assets/Resources/Prefabs/UI/Factory.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 89c2e61af66edfc418938381caf7673f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Prefabs/SampleProject/Factory/AGV.prefab b/Assets/Resources/Prefabs/UI/Factory/AGV.prefab similarity index 100% rename from Assets/Resources/Prefabs/SampleProject/Factory/AGV.prefab rename to Assets/Resources/Prefabs/UI/Factory/AGV.prefab diff --git a/Assets/Resources/Prefabs/SampleProject/Factory/AGV.prefab.meta b/Assets/Resources/Prefabs/UI/Factory/AGV.prefab.meta similarity index 100% rename from Assets/Resources/Prefabs/SampleProject/Factory/AGV.prefab.meta rename to Assets/Resources/Prefabs/UI/Factory/AGV.prefab.meta diff --git a/Assets/Resources/Prefabs/SampleProject/Factory/Alarm.prefab b/Assets/Resources/Prefabs/UI/Factory/Alarm.prefab similarity index 58% rename from Assets/Resources/Prefabs/SampleProject/Factory/Alarm.prefab rename to Assets/Resources/Prefabs/UI/Factory/Alarm.prefab index 88ac3a83..bd80de08 100644 --- a/Assets/Resources/Prefabs/SampleProject/Factory/Alarm.prefab +++ b/Assets/Resources/Prefabs/UI/Factory/Alarm.prefab @@ -92,8 +92,8 @@ MonoBehaviour: m_faceColor: serializedVersion: 2 rgba: 4294967295 - m_fontSize: 36 - m_fontSizeBase: 36 + m_fontSize: 12 + m_fontSizeBase: 12 m_fontWeight: 400 m_enableAutoSizing: 0 m_fontSizeMin: 18 @@ -163,13 +163,16 @@ RectTransform: m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 - m_Children: [] + m_Children: + - {fileID: 7131291007070285513} + - {fileID: 5271924166542973796} + - {fileID: 3646766325915033839} 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_AnchoredPosition: {x: 0, y: -20} + m_SizeDelta: {x: 20, y: 60} m_Pivot: {x: 0.5, y: 0.5} --- !u!1 &1828762385695490929 GameObject: @@ -226,6 +229,292 @@ MonoBehaviour: alarmCountText: {fileID: 8650239058674280921} expandedView: {fileID: 952545100964675415} singleAlarmIconPrefab: {fileID: 7314511769243682470, guid: e9acc8c9a93a2b5409fc01661660b217, type: 3} +--- !u!1 &1960784422133791095 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3646766325915033839} + - component: {fileID: 4629718865595954553} + - component: {fileID: 353088631153534614} + m_Layer: 5 + m_Name: Text (TMP) (1) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3646766325915033839 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1960784422133791095} + 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: 8574585598928791195} + 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 &4629718865595954553 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1960784422133791095} + m_CullTransparentMesh: 1 +--- !u!114 &353088631153534614 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1960784422133791095} + 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: + 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 &3143968334505601971 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7131291007070285513} + - component: {fileID: 7326861565818029875} + - component: {fileID: 927238525312826162} + m_Layer: 5 + m_Name: shadow + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &7131291007070285513 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3143968334505601971} + 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: 8574585598928791195} + 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 &7326861565818029875 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3143968334505601971} + m_CullTransparentMesh: 1 +--- !u!114 &927238525312826162 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3143968334505601971} + 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 &4577807398885837071 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5271924166542973796} + - component: {fileID: 9155506323335068705} + - component: {fileID: 4147791058937629139} + m_Layer: 5 + m_Name: bg + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5271924166542973796 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4577807398885837071} + 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: 8574585598928791195} + 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 &9155506323335068705 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4577807398885837071} + m_CullTransparentMesh: 1 +--- !u!114 &4147791058937629139 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4577807398885837071} + 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: 0.5235849, b: 0.5235849, 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 --- !u!1 &4918696741701580718 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Resources/Prefabs/SampleProject/Factory/Alarm.prefab.meta b/Assets/Resources/Prefabs/UI/Factory/Alarm.prefab.meta similarity index 100% rename from Assets/Resources/Prefabs/SampleProject/Factory/Alarm.prefab.meta rename to Assets/Resources/Prefabs/UI/Factory/Alarm.prefab.meta diff --git a/Assets/Resources/Prefabs/SampleProject/Factory/AlarmIcon.prefab b/Assets/Resources/Prefabs/UI/Factory/AlarmIcon.prefab similarity index 95% rename from Assets/Resources/Prefabs/SampleProject/Factory/AlarmIcon.prefab rename to Assets/Resources/Prefabs/UI/Factory/AlarmIcon.prefab index d2d29662..e8d9fac3 100644 --- a/Assets/Resources/Prefabs/SampleProject/Factory/AlarmIcon.prefab +++ b/Assets/Resources/Prefabs/UI/Factory/AlarmIcon.prefab @@ -35,7 +35,7 @@ RectTransform: 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_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &5770335694761070239 CanvasRenderer: @@ -67,8 +67,8 @@ MonoBehaviour: 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_fontAsset: {fileID: 11400000, guid: 2c77cc500db5adc499bfa50030f7e8c2, type: 2} + m_sharedMaterial: {fileID: -8159279640617175905, guid: 2c77cc500db5adc499bfa50030f7e8c2, type: 2} m_fontSharedMaterials: [] m_fontMaterial: {fileID: 0} m_fontMaterials: [] @@ -92,17 +92,17 @@ MonoBehaviour: m_faceColor: serializedVersion: 2 rgba: 4294967295 - m_fontSize: 12 - m_fontSizeBase: 12 + m_fontSize: 9 + m_fontSizeBase: 9 m_fontWeight: 400 m_enableAutoSizing: 0 m_fontSizeMin: 18 m_fontSizeMax: 72 - m_fontStyle: 0 - m_HorizontalAlignment: 1 - m_VerticalAlignment: 256 + m_fontStyle: 1 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 m_textAlignment: 65535 - m_characterSpacing: 0 + m_characterSpacing: -15 m_wordSpacing: 0 m_lineSpacing: 0 m_lineSpacingMax: 0 @@ -170,8 +170,8 @@ RectTransform: 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_AnchoredPosition: {x: 2.5, y: -2.5} + m_SizeDelta: {x: 5, y: 5} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &2825211744860677609 CanvasRenderer: @@ -248,7 +248,7 @@ RectTransform: 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_SizeDelta: {x: 20, y: 20} m_Pivot: {x: 0.5, y: 0.5} --- !u!114 &5545478218830425297 MonoBehaviour: diff --git a/Assets/Resources/Prefabs/SampleProject/Factory/AlarmIcon.prefab.meta b/Assets/Resources/Prefabs/UI/Factory/AlarmIcon.prefab.meta similarity index 100% rename from Assets/Resources/Prefabs/SampleProject/Factory/AlarmIcon.prefab.meta rename to Assets/Resources/Prefabs/UI/Factory/AlarmIcon.prefab.meta diff --git a/Assets/Resources/Prefabs/SampleProject/UI/InfoWindow.prefab b/Assets/Resources/Prefabs/UI/Factory/InfoWindow.prefab similarity index 100% rename from Assets/Resources/Prefabs/SampleProject/UI/InfoWindow.prefab rename to Assets/Resources/Prefabs/UI/Factory/InfoWindow.prefab diff --git a/Assets/Resources/Prefabs/SampleProject/UI/InfoWindow.prefab.meta b/Assets/Resources/Prefabs/UI/Factory/InfoWindow.prefab.meta similarity index 100% rename from Assets/Resources/Prefabs/SampleProject/UI/InfoWindow.prefab.meta rename to Assets/Resources/Prefabs/UI/Factory/InfoWindow.prefab.meta diff --git a/Assets/Scenes/SampleProject.unity b/Assets/Scenes/SampleProject.unity index 53174c5d..038e71cc 100644 --- a/Assets/Scenes/SampleProject.unity +++ b/Assets/Scenes/SampleProject.unity @@ -277,11 +277,11 @@ GameObject: serializedVersion: 6 m_Component: - component: {fileID: 330585546} + - component: {fileID: 330585549} - component: {fileID: 330585545} - component: {fileID: 330585544} - component: {fileID: 330585547} - component: {fileID: 330585548} - - component: {fileID: 330585549} m_Layer: 0 m_Name: Main Camera m_TagString: MainCamera @@ -435,10 +435,13 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 61deddb674c074049a9b43fd58f1b355, type: 3} m_Name: m_EditorClassIdentifier: - panSpeed: 20 + lowAltitudePanSpeed: 0.5 + highAltitudePanSpeed: 10 rotationSpeed: 300 zoomSpeed: 10 maxPanDelta: 50 + minCameraY: 2 + maxCameraY: 50 --- !u!1 &410087039 GameObject: m_ObjectHideFlags: 0 @@ -926,51 +929,6 @@ 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 @@ -1025,6 +983,121 @@ RectTransform: m_CorrespondingSourceObject: {fileID: 5064510836022735693, guid: 27ddee6261f49584c8634ba7c5f4ae46, type: 3} m_PrefabInstance: {fileID: 8261569461642068635} m_PrefabAsset: {fileID: 0} +--- !u!1 &1087949228 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1087949233} + - component: {fileID: 1087949232} + - component: {fileID: 1087949231} + - component: {fileID: 1087949230} + - component: {fileID: 1087949229} + m_Layer: 5 + m_Name: AlarmManager + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1087949229 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1087949228} + 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!114 &1087949230 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1087949228} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &1087949231 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1087949228} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 0 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 800, y: 600} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 + m_PresetInfoIsWorld: 0 +--- !u!223 &1087949232 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1087949228} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 330585545} + m_PlaneDistance: 100 + m_PixelPerfect: 1 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_VertexColorAlwaysGammaSpace: 0 + m_AdditionalShaderChannelsFlag: 0 + m_UpdateRectTransformForStandalone: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!224 &1087949233 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1087949228} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} --- !u!1 &1091201604 GameObject: m_ObjectHideFlags: 0 @@ -2223,7 +2296,7 @@ SceneRoots: - {fileID: 832575519} - {fileID: 632541407} - {fileID: 27812499} - - {fileID: 784978157} + - {fileID: 1087949233} - {fileID: 2030316712} - {fileID: 483439351} - {fileID: 495653798} diff --git a/Assets/Scripts/SampleProject/AppMain.cs b/Assets/Scripts/SampleProject/AppMain.cs index cc59f3e0..35aa9cf2 100644 --- a/Assets/Scripts/SampleProject/AppMain.cs +++ b/Assets/Scripts/SampleProject/AppMain.cs @@ -52,7 +52,7 @@ namespace SampleProject mqttPipeLine = new MQTTPipeLine("localhost", 1883); mqttPipeLine.AddTopic("AGV"); - //mqttPipeLine.AddTopic("ALARM"); + mqttPipeLine.AddTopic("ALARM"); mqttPipeLine.Execute(); //10รส ศฤ มคม๖ diff --git a/Assets/Scripts/UVC/Data/DataArray.cs b/Assets/Scripts/UVC/Data/DataArray.cs index ebdd62f9..44082a07 100644 --- a/Assets/Scripts/UVC/Data/DataArray.cs +++ b/Assets/Scripts/UVC/Data/DataArray.cs @@ -278,13 +278,20 @@ namespace UVC.Data /// - /// ์—…๋ฐ์ดํŠธ ๋œ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. - /// - /// - public IDataObject GetUpdatedObject() + /// ํ˜„์žฌ ๋ฐ์ดํ„ฐ ๊ฐ์ฒด์˜ ์—…๋ฐ์ดํŠธ๋œ ๋ฒ„์ „์„ ์ƒ์„ฑํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์„ ํƒ์ ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด ํ’€์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. + // + /// ์ด ๋ฉ”์„œ๋“œ๋Š” ํ˜„์žฌ ๋ฐ์ดํ„ฐ ๊ฐ์ฒด์™€ ๊ด€๋ จ ์š”์†Œ์˜ ๊นŠ์€ ๋ณต์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. + /// ์ด ์ด๋ฉด ๋ฉ”์„œ๋“œ๋Š” ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์„ ์ตœ์ ํ™”ํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ์ฒด ํ’€์—์„œ ์ƒˆ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฒ€์ƒ‰ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ƒˆ ์ธ์Šคํ„ด์Šค๊ฐ€ ์ง์ ‘ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ๋ฐ˜ํ™˜๋œ + /// ๊ฐ์ฒด๋Š” ์ถ”๊ฐ€, ์ œ๊ฑฐ ๋ฐ ์ˆ˜์ •์„ ํฌํ•จํ•˜์—ฌ ํ˜„์žฌ ๊ฐ์ฒด์˜ ์ƒํƒœ์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๋ฅผ ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค. + /// ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ์ถ”์ ๋˜์–ด ์—…๋ฐ์ดํŠธ๋œ ๊ฐ์ฒด์˜ ํ•ด๋‹น ๋ชฉ๋ก์— ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. + /// ๊ฐ์ฒด ํ’€์—์„œ ์ƒˆ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฒ€์ƒ‰ํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ถ€์šธ ๊ฐ’์ž…๋‹ˆ๋‹ค. + /// ๊ฐ์ฒด ํ’€์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒˆ ์ธ์Šคํ„ด์Šค๋ฅผ ์ง์ ‘ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. + /// ์ถ”๊ฐ€, ์ œ๊ฑฐ ๋˜๋Š” ์ˆ˜์ •๋œ ๋ชฉ๋ก์—์„œ ์ถ”์ ๋œ ๋ชจ๋“  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ํฌํ•จํ•˜์—ฌ ํ˜„์žฌ ๊ฐ์ฒด ๋ฐ์ดํ„ฐ์˜ ๊นŠ์€ ๋ณต์‚ฌ๋ณธ์„ ํฌํ•จํ•˜๋Š” ์—…๋ฐ์ดํŠธ๋œ ์ธ์Šคํ„ด์Šค์ž…๋‹ˆ๋‹ค. + /// + public IDataObject GetUpdatedObject(bool fromPool = true) { // ํ’€์—์„œ ์ƒˆ DataArray ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. - var clone = DataArrayPool.Get(); + var clone = fromPool ? DataArrayPool.Get() : new DataArray(); clone.FromCapacity(this.Count); // ๋ฐฐ์—ด์˜ ๋ชจ๋“  DataObject๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ ๊ฐ๊ฐ์„ ๋ณต์ œํ•ฉ๋‹ˆ๋‹ค. @@ -292,7 +299,7 @@ namespace UVC.Data { // DataObject์˜ Clone ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๊นŠ์€ ๋ณต์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ณ , // base.Add๋ฅผ ์‚ฌ์šฉํ•ด ์ถ”์  ๋กœ์ง ์—†์ด ์ง์ ‘ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. - if (item.GetUpdatedObject() is DataObject updatedObject) + if (item.GetUpdatedObject(fromPool) is DataObject updatedObject) { clone.Add(updatedObject); if (addedList.Contains(item)) diff --git a/Assets/Scripts/UVC/Data/DataObject.cs b/Assets/Scripts/UVC/Data/DataObject.cs index 0507e629..4cfd606c 100644 --- a/Assets/Scripts/UVC/Data/DataObject.cs +++ b/Assets/Scripts/UVC/Data/DataObject.cs @@ -807,17 +807,37 @@ namespace UVC.Data } /// - /// ์—…๋ฐ์ดํŠธ๋œ ์†์„ฑ๋งŒ ํฌํ•จํ•˜๋Š” ์ƒˆ๋กœ์šด DataObject๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. + /// ํ˜„์žฌ ๊ฐ์ฒด์˜ ์ƒํƒœ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์—…๋ฐ์ดํŠธ๋œ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. /// - /// ์—…๋ฐ์ดํŠธ ๋œ ํ•ญ๋ชฉ๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” DataObject - public IDataObject GetUpdatedObject() + /// ์ด ๋ฉ”์„œ๋“œ๋Š” ๋ฐ ์œ ํ˜•์˜ ์†์„ฑ์€ ๊นŠ์ด ๋ณต์‚ฌ๋˜๊ณ , ๋‹ค๋ฅธ ์œ ํ˜•์˜ ์†์„ฑ์€ ์ง์ ‘ ๋ณต์‚ฌ๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. IdKey๊ฐ€ ์—†์œผ๋ฉด + /// ํ˜„์žฌ ๊ฐ์ฒด์˜ ์ฒซ ๋ฒˆ์งธ ํ‚ค-๊ฐ’ ์Œ์ด ์—…๋ฐ์ดํŠธ๋œ ๊ฐ์ฒด์— ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. + /// + /// ์—…๋ฐ์ดํŠธ๋œ ๊ฐ์ฒด๋ฅผ ํ’€์—์„œ ๊ฒ€์ƒ‰ํ•ด์•ผ ํ•˜๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฐ’์ž…๋‹ˆ๋‹ค. ์ธ ๊ฒฝ์šฐ + /// ์—์„œ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ƒˆ + /// ์ธ์Šคํ„ด์Šค๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. + /// ํ˜„์žฌ ๊ฐ์ฒด์—์„œ ๋ณต์‚ฌ๋œ ์†์„ฑ๊ณผ ๊ฐ’์„ ํฌํ•จํ•˜๋Š” ์—…๋ฐ์ดํŠธ๋œ ์ธ์Šคํ„ด์Šค์ž…๋‹ˆ๋‹ค. + /// ๋ฐ˜ํ™˜๋œ ๊ฐ์ฒด์—๋Š” ๋ณ€๊ฒฝ๋œ ๋ชจ๋“  ์†์„ฑ, IdKey ๋ฐ Name์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. + /// IdKey๊ฐ€ ํ˜„์žฌ ๊ฐ์ฒด์— ์žˆ๋Š” ๊ฒฝ์šฐ ํ•ด๋‹น ๊ฐ’๋„ ์—…๋ฐ์ดํŠธ๋œ ๊ฐ์ฒด์— ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. + public IDataObject GetUpdatedObject(bool fromPool = true) { - DataObject updated = DataObjectPool.Get(); + DataObject updated = fromPool ? DataObjectPool.Get() : new DataObject(); foreach (var key in changedProperies) { if (this.ContainsKey(key)) { - updated[key] = this[key]; + if(this[key] is DataObject dataObject) + { + updated[key] = dataObject.Copy(fromPool); // DataObject๋Š” ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค. + } + else if (this[key] is DataArray dataArray) + { + updated[key] = dataArray.Copy(fromPool); // DataArray๋Š” ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค. + } + else + { + updated[key] = this[key]; // ๊ทธ ์™ธ์˜ ๊ฐ’์€ ๊ทธ๋Œ€๋กœ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค. + } } } updated.IdKey = IdKey; // ID ํ‚ค๋ฅผ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค. diff --git a/Assets/Scripts/UVC/Data/DataObjectPool.cs b/Assets/Scripts/UVC/Data/DataObjectPool.cs index 62341663..6419ca0a 100644 --- a/Assets/Scripts/UVC/Data/DataObjectPool.cs +++ b/Assets/Scripts/UVC/Data/DataObjectPool.cs @@ -38,7 +38,7 @@ namespace UVC.Data /// /// ํ’€์˜ ์ตœ๋Œ€ ํฌ๊ธฐ์ž…๋‹ˆ๋‹ค. ์ด ํฌ๊ธฐ๋ฅผ ์ดˆ๊ณผํ•˜๋Š” ๊ฐ์ฒด๋Š” ํ’€์— ์ €์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. /// - private static int maxPoolSize = 4000; + private static int maxPoolSize = 2000; // --- ํ†ต๊ณ„์šฉ ํ•„๋“œ --- private static int _inUseCount = 0; // ํ˜„์žฌ ์‚ฌ์šฉ ์ค‘์ธ DataObject ์ธ์Šคํ„ด์Šค์˜ ์ˆ˜ diff --git a/Assets/Scripts/UVC/Data/DataRepository.cs b/Assets/Scripts/UVC/Data/DataRepository.cs index 1f9f9f10..e999ec5d 100644 --- a/Assets/Scripts/UVC/Data/DataRepository.cs +++ b/Assets/Scripts/UVC/Data/DataRepository.cs @@ -69,7 +69,7 @@ namespace UVC.Data { if (!dataObjects.ContainsKey(key)) { - var newData = dataObject.Clone(false); + var newData = dataObject.Clone(fromPool: false); dataObjects.Add(key, newData); dataObject.MarkAllAsUpdated(); @@ -83,7 +83,7 @@ namespace UVC.Data IDataObject newDataObject; if (updatedDataOnly) { - newDataObject = obj.GetUpdatedObject(); + newDataObject = obj.GetUpdatedObject(fromPool: false); } else { diff --git a/Assets/Scripts/UVC/Data/HttpPipeLine.cs b/Assets/Scripts/UVC/Data/HttpPipeLine.cs index a684b51b..aa2f0c3e 100644 --- a/Assets/Scripts/UVC/Data/HttpPipeLine.cs +++ b/Assets/Scripts/UVC/Data/HttpPipeLine.cs @@ -431,7 +431,7 @@ namespace UVC.Data if (mappedObject != null) { repoObject = DataRepository.Instance.AddData(key, mappedObject, info.UpdatedDataOnly); - if (repoObject == mappedObject) repoObject = mappedObject.Clone(); + if (repoObject == mappedObject) repoObject = mappedObject.Clone(fromPool: false); } diff --git a/Assets/Scripts/UVC/Data/IDataObject.cs b/Assets/Scripts/UVC/Data/IDataObject.cs index 80ed6238..b7ee4b96 100644 --- a/Assets/Scripts/UVC/Data/IDataObject.cs +++ b/Assets/Scripts/UVC/Data/IDataObject.cs @@ -26,8 +26,9 @@ /// /// ์—…๋ฐ์ดํŠธ๋œ ์†์„ฑ๋งŒ ํฌํ•จํ•˜๋Š” ์ƒˆ๋กœ์šด DataObject๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. /// + /// ๊ฐ์ฒด ํ’€์—์„œ ๋ณต์ œํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ true์ž…๋‹ˆ๋‹ค. /// ์—…๋ฐ์ดํŠธ ๋œ ํ•ญ๋ชฉ๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” DataObject - public IDataObject GetUpdatedObject(); + public IDataObject GetUpdatedObject(bool fromPool = true); /// /// /// diff --git a/Assets/Scripts/UVC/Data/MQTTPipeLine.cs b/Assets/Scripts/UVC/Data/MQTTPipeLine.cs index b6dcc377..5291e0b6 100644 --- a/Assets/Scripts/UVC/Data/MQTTPipeLine.cs +++ b/Assets/Scripts/UVC/Data/MQTTPipeLine.cs @@ -245,7 +245,7 @@ namespace UVC.Data if (mappedObject == null) return; // DataRepository๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณต์‚ฌ/์—…๋ฐ์ดํŠธํ•˜๋ฏ€๋กœ, mappedObject๋Š” ์—ฌ๊ธฐ์„œ ์ž„์‹œ ๊ฐ์ฒด๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. var repoObject = DataRepository.Instance.AddData(topic, mappedObject, info.UpdatedDataOnly); - if(repoObject == mappedObject) repoObject = mappedObject.Clone(); + if(repoObject == mappedObject) repoObject = mappedObject.Clone(fromPool: false); // ํ•ธ๋“ค๋Ÿฌ ํ˜ธ์ถœ์ด ํ•„์š”ํ•œ์ง€ ํ™•์ธ bool shouldInvoke = !info.UpdatedDataOnly || (repoObject != null && repoObject.UpdatedCount > 0); if (shouldInvoke) diff --git a/Assets/Scripts/UVC/Factory/Alarm/AlarmManager.cs b/Assets/Scripts/UVC/Factory/Alarm/AlarmManager.cs index 1c924d2f..8f233fd2 100644 --- a/Assets/Scripts/UVC/Factory/Alarm/AlarmManager.cs +++ b/Assets/Scripts/UVC/Factory/Alarm/AlarmManager.cs @@ -9,18 +9,24 @@ using UVC.Core; using UVC.Data; using UVC.Extention; using UVC.Factory.Component; +using UVC.Util; namespace UVC.Factory.Alarm { public class AlarmManager : SingletonScene { [Tooltip("์•Œ๋žŒ UI ํ”„๋ฆฌํŒน์ž…๋‹ˆ๋‹ค. ์ด ํ”„๋ฆฌํŒน์€ ์•Œ๋žŒ ์ •๋ณด๋ฅผ ํ‘œ์‹œํ•˜๋Š” UI ์š”์†Œ๋ฅผ ํฌํ•จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.")] - public GameObject alarmUIPrefab; // ์•Œ๋žŒ UI ํ”„๋ฆฌํŒน (์•„๋ž˜์—์„œ ์„ค๋ช…) + [SerializeField] + protected GameObject alarmUIPrefab; // ์•Œ๋žŒ UI ํ”„๋ฆฌํŒน (์•„๋ž˜์—์„œ ์„ค๋ช…) private Dictionary activeAlarmUIs = new Dictionary(); + private List agvNames = new List(); + private Dictionary alarmAgvNames = new Dictionary(); + // FactoryDataManager์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ๋„๋ก ์ฐธ์กฐ๋ฅผ ์ €์žฅ private FactoryObjectManager? dataManager; + /// /// AlarmManager์˜ ์ดˆ๊ธฐํ™” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค. /// Awake ๋ฉ”์„œ๋“œ์—์„œ ํ˜ธ์ถœ๋˜๋ฉฐ, MonoBehaviour๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. @@ -33,8 +39,17 @@ namespace UVC.Factory.Alarm private void OnSceneInitialized() { dataManager = FactoryObjectManager.Instance; + + //test code + //์•Œ๋žŒ ๋ฐ์ดํ„ฐ๊ฐ€ AGV์™€ ๊ด€๋ จ ์—†๋Š”๊ฒƒ์ด ๋งŽ์•„์„œ, AGV ์ด๋ฆ„์„ ๋ฏธ๋ฆฌ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. + for (int i = 1; i <= 115; i++) + { + agvNames.Add($"HFF09CNA8{i.ToString("D3")}"); + } } + + /// /// Alarm ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์‹ ํ•˜๊ธฐ ์œ„ํ•œ MQTT ํŒŒ์ดํ”„๋ผ์ธ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. /// @@ -58,6 +73,7 @@ namespace UVC.Factory.Alarm dataMask["TRANSPORT_UNIT_NAME"] = ""; dataMask["TRANSPORT_EQP_ID"] = ""; dataMask["TRANSPORT_UNIT_ID"] = ""; + dataMask["CLEAR_TIME"] = DateTime.Now; dataMask["SET_TIME"] = DateTime.Now; dataMask["UPDATE_TIME"] = DateTime.Now; dataMask["TIMESTAMP"] = DateTime.Now; @@ -78,6 +94,9 @@ namespace UVC.Factory.Alarm // ์ƒ์„ฑํ•œ ํŒŒ์ดํ”„๋ผ์ธ ์ •๋ณด๋ฅผ ์ „์—ญ MQTT ํŒŒ์ดํ”„๋ผ์ธ์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. AppMain.Instance.MQTTPipeLine.Add(pipelineInfo); } + + int agvIdx = 50; + /// /// ๋ฐ์ดํ„ฐ ์ˆ˜์‹  ์‹œ ํ˜ธ์ถœ๋˜๋Š” ๊ณต๊ฐœ ํ•ธ๋“ค๋Ÿฌ์ž…๋‹ˆ๋‹ค. /// ์ˆ˜์‹ ๋œ ALARM ๋ฐ์ดํ„ฐ ๋ฐฐ์—ด์„ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜์—ฌ ์”ฌ์— ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค. @@ -86,43 +105,67 @@ namespace UVC.Factory.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; - } + if (arr == null || arr.Count == 0) return; // ๋ฐ์ดํ„ฐ ๋ฐฐ์—ด์—์„œ ์ถ”๊ฐ€, ์ œ๊ฑฐ, ์ˆ˜์ •๋œ ํ•ญ๋ชฉ ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. var AddedItems = arr.AddedItems; - var RemovedItems = arr.RemovedItems; + var RemovedItems = new List(arr.RemovedItems); var ModifiedList = arr.ModifiedList; Debug.Log($"AlarmManager OnUpdateData: Added={AddedItems.Count}, Removed={RemovedItems.Count}, Modified={ModifiedList.Count}"); + // clear_time์ด ์žˆ๋Š” ํ•ญ๋ชฉ๋งŒ ์ œ๊ฑฐ ๋ฆฌ์ŠคํŠธ์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. + foreach (var item in AddedItems.ToList()) + { + if (item.GetDateTime("CLEAR_TIME") != null) + { + if (RemovedItems.FindIndex((i) => i.Id == item.Id) == -1) RemovedItems.Add(item); + } + } + + foreach (var item in ModifiedList.ToList()) + { + if (item.GetDateTime("CLEAR_TIME") != null) + { + if (RemovedItems.FindIndex((i) => i.Id == item.Id) == -1) RemovedItems.Add(item); + } + } + // ์ƒˆ๋กœ ์ถ”๊ฐ€๋œ ALARM ์ฒ˜๋ฆฌ foreach (var item in AddedItems.ToList()) { - HandleNewAlarm(item.Copy()); - } - - // ์ œ๊ฑฐ๋œ ALARM ์ฒ˜๋ฆฌ - foreach (var item in RemovedItems.ToList()) - { - HandleClearedAlarm(item.Copy()); + if (item.GetDateTime("CLEAR_TIME") == null && !item.Id.IsNullOrEmpty()) + { + item["TRANSPORT_EQP_ID"] = agvNames[agvIdx]; // AGV ์ด๋ฆ„์„ TRANSPORT_EQP_ID์— ์„ค์ • + alarmAgvNames.Add(item.Id!, agvNames[agvIdx]); + HandleNewAlarm(item); + agvIdx++; + if(agvIdx >= agvNames.Count) agvIdx = 0; // AGV ์ด๋ฆ„์ด ๋ถ€์กฑํ•  ๊ฒฝ์šฐ ์ˆœํ™˜ + } } // ์ •๋ณด๊ฐ€ ์ˆ˜์ •๋œ ALARM ์ฒ˜๋ฆฌ foreach (var item in ModifiedList.ToList()) { - HandleModifyAlarm(item.Copy()); + if (item.GetDateTime("CLEAR_TIME") == null && !item.Id.IsNullOrEmpty() && alarmAgvNames.ContainsKey(item.Id!)) + { + item["TRANSPORT_EQP_ID"] = alarmAgvNames[item.Id!]; // ๊ธฐ์กด AGV ์ด๋ฆ„ ์œ ์ง€ + HandleModifyAlarm(item); + } } - arr.ReturnToPool(); + // ์ œ๊ฑฐ๋œ ALARM ์ฒ˜๋ฆฌ + foreach (var item in RemovedItems.ToList()) + { + if (!item.Id.IsNullOrEmpty() && alarmAgvNames.ContainsKey(item.Id!)) + { + item["TRANSPORT_EQP_ID"] = alarmAgvNames[item.Id!]; // ๊ธฐ์กด AGV ์ด๋ฆ„ ์œ ์ง€ + HandleClearedAlarm(item); + } + } } /// @@ -140,12 +183,12 @@ namespace UVC.Factory.Alarm if (data.Id == null) { Debug.LogError($"New Alarm Received No data. {data}"); - data.ReturnToPool(); return; } // ์—†์œผ๋ฉด ์ƒˆ๋กœ ์ƒ์„ฑ - FactoryObject? targetObject = dataManager!.FindById(data.GetString("MACHINENAME")!); + FactoryObject? targetObject = dataManager!.FindByName(data.GetString("TRANSPORT_EQP_ID")!); + Debug.Log($"AlarmManager {targetObject==null} {data.Id}, {data.GetString("TRANSPORT_EQP_ID")}"); if (targetObject != null) { GameObject newUIObject = Instantiate(alarmUIPrefab, transform); // ๋งค๋‹ˆ์ € ํ•˜์œ„์— ์ƒ์„ฑ @@ -162,7 +205,6 @@ namespace UVC.Factory.Alarm if (data.Id == null) { Debug.LogError($"Modify Alarm Received No data. {data}"); - data.ReturnToPool(); return; } // ์ด๋ฏธ ํ•ด๋‹น ์„ค๋น„์— ์•Œ๋žŒ UI๊ฐ€ ๋–  ์žˆ๋Š”์ง€ ํ™•์ธ @@ -178,7 +220,6 @@ namespace UVC.Factory.Alarm if (data.Id.IsNullOrEmpty()) { Debug.LogError($"Clear Alarm Received No data. {data}"); - data.ReturnToPool(); return; } if (activeAlarmUIs.TryGetValue(data.Id!, out AlarmUIController uiController)) @@ -189,7 +230,6 @@ namespace UVC.Factory.Alarm activeAlarmUIs.Remove(data.Id!); Destroy(uiController.gameObject); } - data.ReturnToPool(); } } } diff --git a/Assets/Scripts/UVC/Factory/Alarm/AlarmUIController.cs b/Assets/Scripts/UVC/Factory/Alarm/AlarmUIController.cs index 2b7ce080..c98a8d1f 100644 --- a/Assets/Scripts/UVC/Factory/Alarm/AlarmUIController.cs +++ b/Assets/Scripts/UVC/Factory/Alarm/AlarmUIController.cs @@ -1,4 +1,5 @@ -๏ปฟusing System.Collections.Generic; +๏ปฟusing DG.Tweening; +using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.EventSystems; @@ -22,6 +23,21 @@ namespace UVC.Factory.Alarm private Transform targetObject; private List alarms = new List(); private bool isExpanded = false; + private SingleAlarmIcon singleAlarmIcon1 = null; + + private RectTransform rectTransform; + private Canvas mainCanvas; + + private float uiSpacing = 20f; // ๊ฐ„๊ฒฉ + private Tweener uiSpacingTweener; + + private bool isZoomIn = false; // ์คŒ ์ธ ์ƒํƒœ๋ฅผ ์ถ”์ ํ•˜๊ธฐ ์œ„ํ•œ ๋ณ€์ˆ˜ + + private void Awake() + { + rectTransform = GetComponent(); + mainCanvas = GetComponentInParent(); + } public void Initialize(FactoryObject target, DataObject initialAlarm) { @@ -31,9 +47,56 @@ namespace UVC.Factory.Alarm void LateUpdate() { - // ๋นŒ๋ณด๋“œ ํšจ๊ณผ: ํ•ญ์ƒ ์นด๋ฉ”๋ผ๋ฅผ ๋ฐ”๋ผ๋ณด๋„๋ก ํ•˜๊ณ , ํƒ€๊ฒŸ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๋”ฐ๋ผ๋‹ค๋‹˜ - transform.position = targetObject.position + Vector3.up * 2.0f; // ์˜ˆ์‹œ: ๋จธ๋ฆฌ ์œ„ 2๋ฏธํ„ฐ - transform.rotation = Camera.main.transform.rotation; + if (targetObject == null || Camera.main == null || mainCanvas == null) + { + // ํ•„์ˆ˜ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์—†์œผ๋ฉด UI๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค. + if (clusterView.activeSelf) clusterView.SetActive(false); + if (expandedView.activeSelf) expandedView.SetActive(false); + if (alarmCountText != null && alarmCountText.gameObject.activeSelf) alarmCountText.gameObject.SetActive(false); + if (singleAlarmIcon1 != null && singleAlarmIcon1.gameObject.activeSelf) singleAlarmIcon1.gameObject.SetActive(false); + return; + } + + // ์นด๋ฉ”๋ผ์˜ ์ •๋ฉด ๋ฐฉํ–ฅ๊ณผ ํƒ€๊ฒŸ์„ ํ–ฅํ•˜๋Š” ๋ฐฉํ–ฅ์„ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. + Vector3 cameraForward = Camera.main.transform.forward; + Vector3 toTarget = (targetObject.position - Camera.main.transform.position).normalized; + + // ๋‘ ๋ฒกํ„ฐ์˜ ๋‚ด์ ์„ ๊ณ„์‚ฐํ•˜์—ฌ ํƒ€๊ฒŸ์ด ์นด๋ฉ”๋ผ ์•ž์— ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. + // ๋‚ด์  ๊ฐ’์ด 0๋ณด๋‹ค ํฌ๋ฉด ํƒ€๊ฒŸ์ด ์นด๋ฉ”๋ผ ์•ž์— ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. + if (Vector3.Dot(cameraForward, toTarget) > 0) + { + // ํƒ€๊ฒŸ์ด ์•ž์— ์žˆ์„ ๋•Œ๋งŒ UI๋ฅผ ํ™œ์„ฑํ™”ํ•˜๊ณ  ์œ„์น˜๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค. + if (!gameObject.activeSelf) + { + UpdateView(); // ๋น„ํ™œ์„ฑํ™” ์ƒํƒœ์˜€๋‹ค๋ฉด ๋ทฐ๋ฅผ ๋‹ค์‹œ ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค. + } + + // targetObject์˜ ์›”๋“œ ์ขŒํ‘œ๋ฅผ ์Šคํฌ๋ฆฐ ์ขŒํ‘œ๋กœ ๋ณ€ํ™˜ + Vector3 screenPoint = Camera.main.WorldToScreenPoint(targetObject.position + Vector3.up); + + // Canvas Render Mode๊ฐ€ Screen Space - Camera์ผ ๊ฒฝ์šฐ + if (mainCanvas.renderMode == RenderMode.ScreenSpaceCamera) + { + Vector2 localPoint; + RectTransformUtility.ScreenPointToLocalPointInRectangle(mainCanvas.transform as RectTransform, screenPoint, mainCanvas.worldCamera, out localPoint); + localPoint.y += uiSpacing; + rectTransform.localPosition = localPoint; + } + // Canvas Render Mode๊ฐ€ Screen Space - Overlay์ผ ๊ฒฝ์šฐ + else + { + screenPoint.y += uiSpacing; + rectTransform.position = screenPoint; + } + } + else + { + // ํƒ€๊ฒŸ์ด ์นด๋ฉ”๋ผ ๋’ค์— ์žˆ์œผ๋ฉด ๋ชจ๋“  ๊ด€๋ จ UI๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค. + if (clusterView.activeSelf) clusterView.SetActive(false); + if (expandedView.activeSelf) expandedView.SetActive(false); + if (alarmCountText != null && alarmCountText.gameObject.activeSelf) alarmCountText.gameObject.SetActive(false); + if (singleAlarmIcon1 != null && singleAlarmIcon1.gameObject.activeSelf) singleAlarmIcon1.gameObject.SetActive(false); + } } public void AddAlarm(DataObject alarm) @@ -52,7 +115,6 @@ namespace UVC.Factory.Alarm { alarms[index][key] = alarm[key]; // ๊ธฐ์กด ์•Œ๋žŒ ๋ฐ์ดํ„ฐ ์—…๋ฐ์ดํŠธ } - alarm.ReturnToPool(); UpdateView(); } else @@ -81,14 +143,23 @@ namespace UVC.Factory.Alarm if (alarms.Count > 1) { clusterView.SetActive(true); - expandedView.SetActive(false); // ๋‹จ์ผ ๋ทฐ๋„ ๊บผ์•ผ ํ•จ + expandedView.SetActive(false); + if (singleAlarmIcon1 != null) singleAlarmIcon1.gameObject.SetActive(false); // ๋‹จ์ผ ๋ทฐ๋„ ๊บผ์•ผ ํ•จ + alarmCountText.gameObject.SetActive(true); alarmCountText.text = alarms.Count.ToString(); } else if (alarms.Count == 1) { clusterView.SetActive(false); expandedView.SetActive(false); + alarmCountText.gameObject.SetActive(false); // ์•Œ๋žŒ ๊ฐœ์ˆ˜ ํ…์ŠคํŠธ ์ˆจ๊น€ // ์—ฌ๊ธฐ์— ๋‹จ์ผ ์•Œ๋žŒ ์•„์ด์ฝ˜์„ ๋ณด์—ฌ์ฃผ๋Š” ๋กœ์ง ์ถ”๊ฐ€ + if (singleAlarmIcon1 == null) + { + singleAlarmIcon1 = Instantiate(singleAlarmIconPrefab, transform).GetComponent(); + } + singleAlarmIcon1.gameObject.SetActive(true); + singleAlarmIcon1.SetData(alarms[0], targetObject); } } } @@ -103,14 +174,18 @@ namespace UVC.Factory.Alarm { if (alarms.Count > 1) { + isZoomIn = true; // ํด๋Ÿฌ์Šคํ„ฐ ํ™•์žฅ - CameraController.Instance.FocusOnTarget(transform, 5.0f); // ์˜ˆ์‹œ: 5๋ฏธํ„ฐ ๊ฑฐ๋ฆฌ๋กœ ์คŒ + CameraController.Instance.FocusOnTarget(targetObject.position, 15.0f); // ์˜ˆ์‹œ: 5๋ฏธํ„ฐ ๊ฑฐ๋ฆฌ๋กœ ์คŒ ExpandCluster(); } else if (alarms.Count == 1) { + isZoomIn = true; + //AnimateUISpace(1f); // ๊ฐ„๊ฒฉ์„ 0์œผ๋กœ ์• ๋‹ˆ๋ฉ”์ด์…˜ + // ๋‹จ์ผ ์•Œ๋žŒ ํด๋ฆญ - CameraController.Instance.FocusOnTarget(targetObject, 3.0f); + CameraController.Instance.FocusOnTarget(targetObject.position, 10.0f); // ์ถ”๊ฐ€๋กœ ์•Œ๋žŒ ์ƒ์„ธ ์ •๋ณด UI๋ฅผ ๋„์šธ ์ˆ˜ ์žˆ์Œ } } @@ -121,6 +196,7 @@ namespace UVC.Factory.Alarm isExpanded = true; clusterView.SetActive(false); expandedView.SetActive(true); + singleAlarmIcon1.gameObject.SetActive(false); // ๊ธฐ์กด ์•„์ด์ฝ˜๋“ค ์‚ญ์ œ foreach (Transform child in expandedView.transform) @@ -129,16 +205,19 @@ namespace UVC.Factory.Alarm } // ์›ํ˜•์œผ๋กœ ์•„์ด์ฝ˜ ๋ฐฐ์น˜ + float radius = 100.0f; // Canvas ์ขŒํ‘œ๊ณ„์— ๋งž๋Š” ๋ฐ˜์ง€๋ฆ„ ๊ฐ’ for (int i = 0; i < alarms.Count; i++) { float angle = i * Mathf.PI * 2f / alarms.Count; - Vector3 pos = new Vector3(Mathf.Cos(angle), Mathf.Sin(angle), 0) * 0.5f; // 0.5f๋Š” ๋ฐ˜์ง€๋ฆ„ + Vector3 pos = new Vector3(Mathf.Cos(angle), Mathf.Sin(angle), 0) * radius; GameObject iconObj = Instantiate(singleAlarmIconPrefab, expandedView.transform); iconObj.transform.localPosition = pos; // iconObj์˜ SingleAlarmIcon ์Šคํฌ๋ฆฝํŠธ์— ์•Œ๋žŒ ๋ฐ์ดํ„ฐ ์ „๋‹ฌ iconObj.GetComponent().SetData(alarms[i], targetObject); } + + //AnimateUISpace(0f); // ๊ฐ„๊ฒฉ์„ 0์œผ๋กœ ์• ๋‹ˆ๋ฉ”์ด์…˜ } private void CollapseCluster() @@ -153,5 +232,25 @@ namespace UVC.Factory.Alarm { OnPointerClick(); } + + private void AnimateUISpace(float targetSpacing, float duration = 1.0f) + { + if (uiSpacingTweener != null && uiSpacingTweener.IsActive() && uiSpacingTweener.IsPlaying()) + { + uiSpacingTweener.Kill(); + } + uiSpacingTweener = DOVirtual.Float(uiSpacing, targetSpacing, duration, (value) => + { + uiSpacing = value; + }); + } + + private void OnDestroy() + { + if (uiSpacingTweener != null && uiSpacingTweener.IsActive() && uiSpacingTweener.IsPlaying()) + { + uiSpacingTweener.Kill(); + } + } } } diff --git a/Assets/Scripts/UVC/Factory/Alarm/SingleAlarmIcon.cs b/Assets/Scripts/UVC/Factory/Alarm/SingleAlarmIcon.cs index 9173fd3d..1841bf79 100644 --- a/Assets/Scripts/UVC/Factory/Alarm/SingleAlarmIcon.cs +++ b/Assets/Scripts/UVC/Factory/Alarm/SingleAlarmIcon.cs @@ -33,23 +33,17 @@ namespace UVC.Factory.Alarm equipmentTransform = equipment; - if (text != null) + string icon = data.GetString("ICON"); + if (text != null && icon != null) { - string combinedString = string.Empty; - foreach (var kvp in data) - { - // ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ค„๋ฐ”๊ฟˆ ์‹œ์—๋„ ์ •๋ ฌ์ด ์œ ์ง€๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. - combinedString += $"{kvp.Key}{kvp.Value ?? "null"}\n"; - } - combinedString = combinedString.TrimEnd('\n'); // ๋งˆ์ง€๋ง‰ ์ค„๋ฐ”๊ฟˆ ์ œ๊ฑฐ - text.text = combinedString; + text.text = icon; } } public void OnPointerClick() { // ํด๋ฆญ ์‹œ ํ•ด๋‹น ์„ค๋น„๋กœ ์นด๋ฉ”๋ผ ํฌ์ปค์Šค - CameraController.Instance.FocusOnTarget(equipmentTransform, 3.0f); + CameraController.Instance.FocusOnTarget(equipmentTransform.position, 3.0f); Debug.Log($"์•Œ๋žŒ [{data.GetString("MESSAGE")}]์ด ๋ฐœ์ƒํ•œ ์„ค๋น„๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค."); // ์—ฌ๊ธฐ์„œ ์•Œ๋žŒ ์ƒ์„ธ์ •๋ณด ํŒจ๋„์„ ๋„์›Œ๋„ ์ข‹์Œ } diff --git a/Assets/Scripts/UVC/Factory/Component/AGV.cs b/Assets/Scripts/UVC/Factory/Component/AGV.cs index 2c193cc0..b8dd5b67 100644 --- a/Assets/Scripts/UVC/Factory/Component/AGV.cs +++ b/Assets/Scripts/UVC/Factory/Component/AGV.cs @@ -91,7 +91,6 @@ namespace UVC.Factory.Component data[keyValue.Key] = keyValue.Value; } } - newData.ReturnToPool(); // ์‚ฌ์šฉ์ด ๋๋‚œ ๋ฐ์ดํ„ฐ ๊ฐ์ฒด๋ฅผ ํ’€์— ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. } } diff --git a/Assets/Scripts/UVC/Factory/Component/AGVManager.cs b/Assets/Scripts/UVC/Factory/Component/AGVManager.cs index ed73e4ba..1f0fb122 100644 --- a/Assets/Scripts/UVC/Factory/Component/AGVManager.cs +++ b/Assets/Scripts/UVC/Factory/Component/AGVManager.cs @@ -79,7 +79,7 @@ namespace UVC.Factory.Component public class AGVManager : SingletonScene { - private readonly string prefabPath = "Prefabs/SampleProject/Factory/AGV"; + private readonly string prefabPath = "Prefabs/UI/Factory/AGV"; private GameObjectPool? agvPool; public GameObjectPool AGVPool @@ -178,12 +178,7 @@ namespace UVC.Factory.Component if (data == null || agvPool == null) return; DataArray? arr = data as DataArray; - if (arr == null) return; - if (arr.Count == 0) - { - arr.ReturnToPool(); - return; - } + if (arr == null || arr.Count == 0) return; // ๋ฐ์ดํ„ฐ ๋ฐฐ์—ด์—์„œ ์ถ”๊ฐ€, ์ œ๊ฑฐ, ์ˆ˜์ •๋œ ํ•ญ๋ชฉ ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. var AddedItems = arr.AddedItems; @@ -208,7 +203,7 @@ namespace UVC.Factory.Component "", item.GetString("MODE") ); - agv.UpdateData(item.Copy()); + agv.UpdateData(item); } // ์ œ๊ฑฐ๋œ AGV ์ฒ˜๋ฆฌ @@ -225,16 +220,14 @@ namespace UVC.Factory.Component // ์ •๋ณด๊ฐ€ ์ˆ˜์ •๋œ AGV ์ฒ˜๋ฆฌ foreach (var item in ModifiedList.ToList()) { - 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.Copy()); + agv.UpdateData(item); } } - arr.ReturnToPool(); if(created == false) { created = true; diff --git a/Assets/Scripts/UVC/Factory/Component/FactoryObject.cs b/Assets/Scripts/UVC/Factory/Component/FactoryObject.cs index 971d61e5..d7acc9cc 100644 --- a/Assets/Scripts/UVC/Factory/Component/FactoryObject.cs +++ b/Assets/Scripts/UVC/Factory/Component/FactoryObject.cs @@ -127,10 +127,10 @@ namespace UVC.Factory.Component set { info = value; - if (value != null) + if (info != null) { // ๊ฐ์ฒด์˜ ์ด๋ฆ„์„ GameObject์˜ ์ด๋ฆ„์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. - gameObject.name = value.Name; + gameObject.name = info.Name; FactoryObjectManager.Instance.RegisterFactoryObject(this); } } diff --git a/Assets/Scripts/UVC/Util/CameraController.cs b/Assets/Scripts/UVC/Util/CameraController.cs index 196a2c34..4dc6ddac 100644 --- a/Assets/Scripts/UVC/Util/CameraController.cs +++ b/Assets/Scripts/UVC/Util/CameraController.cs @@ -1,6 +1,7 @@ ๏ปฟusing System; using System.Collections; using UnityEngine; +using UnityEngine.UIElements; using UVC.Core; namespace UVC.Util @@ -13,8 +14,12 @@ namespace UVC.Util /// public class CameraController : SingletonScene { - [Tooltip("์นด๋ฉ”๋ผ ํ‰ํ–‰ ์ด๋™ ์†๋„")] - public float panSpeed = 20f; + [Header("Panning Speed")] + [Tooltip("์นด๋ฉ”๋ผ ๋†’์ด๊ฐ€ ์ž„๊ณ„๊ฐ’๋ณด๋‹ค ๋‚ฎ์„ ๋•Œ์˜ ํ‰ํ–‰ ์ด๋™ ์†๋„")] + public float lowAltitudePanSpeed = 0.5f; + + [Tooltip("์นด๋ฉ”๋ผ ๋†’์ด๊ฐ€ ์ž„๊ณ„๊ฐ’๋ณด๋‹ค ๋†’์„ ๋•Œ์˜ ํ‰ํ–‰ ์ด๋™ ์†๋„")] + public float highAltitudePanSpeed = 10f; [Tooltip("์นด๋ฉ”๋ผ ํšŒ์ „ ์†๋„")] public float rotationSpeed = 300f; @@ -26,16 +31,167 @@ namespace UVC.Util [Tooltip("ํŒจ๋‹ ์‹œ ๋งˆ์šฐ์Šค ์ด๋™๋Ÿ‰์˜ ์ตœ๋Œ€๊ฐ’์„ ์ œํ•œํ•˜์—ฌ, ํ”„๋ ˆ์ž„ ๋“œ๋ž ์‹œ ์นด๋ฉ”๋ผ๊ฐ€ ๊ธ‰๊ฒฉํ•˜๊ฒŒ ํŠ€๋Š” ํ˜„์ƒ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.")] public float maxPanDelta = 50f; + [Header("Camera")] + [Tooltip("์นด๋ฉ”๋ผ ์ตœ์†Œ ๋†’์ด")] + public float minCameraY = 2f; + + [Tooltip("์นด๋ฉ”๋ผ ์ตœ๋Œ€ ๋†’์ด")] + public float maxCameraY = 50f; + + [Tooltip("์นด๋ฉ”๋ผ์˜ ์ตœ์†Œ ์ˆ˜์ง ํšŒ์ „ ๊ฐ๋„ (X์ถ•)")] + public float minPitch = 20f; + + [Tooltip("์นด๋ฉ”๋ผ์˜ ์ตœ๋Œ€ ์ˆ˜์ง ํšŒ์ „ ๊ฐ๋„ (X์ถ•)")] + public float maxPitch = 85f; + + [Tooltip("์นด๋ฉ”๋ผ์˜ ์ตœ์†Œ ์ˆ˜ํ‰ ํšŒ์ „ ๊ฐ๋„ (y์ถ•)")] + public float minYaw = -45f; + + [Tooltip("์นด๋ฉ”๋ผ์˜ ์ตœ๋Œ€ ์ˆ˜ํ‰ ํšŒ์ „ ๊ฐ๋„ (y์ถ•)")] + public float maxYaw = 45f; + + /// + /// ์นด๋ฉ”๋ผ์˜ ๋ณ€ํ˜•์ด ๋ณ€๊ฒฝ๋  ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. + /// + /// ์ด ์ด๋ฒคํŠธ๋Š” ์นด๋ฉ”๋ผ์˜ ๋ณ€ํ˜•์ด ์—…๋ฐ์ดํŠธ๋  ๋•Œ๋งˆ๋‹ค ํŠธ๋ฆฌ๊ฑฐ๋˜๋ฉฐ, + /// ๊ตฌ๋…์ž๋Š” ์œ„์น˜, ํšŒ์ „ ๋˜๋Š” ํฌ๊ธฐ ๋ณ€๊ฒฝ์— ์‘๋‹ตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์ด๋ฒคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ + /// UI ์š”์†Œ ์—…๋ฐ์ดํŠธ ๋˜๋Š” ์ข…์† ๊ฐ’ ์žฌ๊ณ„์‚ฐ๊ณผ ๊ฐ™์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + public event Action OnCameraChanged; + + /// + /// ์นด๋ฉ”๋ผ ์œ„์น˜๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. + /// + /// ์ด ์ด๋ฒคํŠธ๋Š” ์นด๋ฉ”๋ผ ์œ„์น˜๊ฐ€ ์—…๋ฐ์ดํŠธ๋  ๋•Œ๋งˆ๋‹ค ํŠธ๋ฆฌ๊ฑฐ๋ฉ๋‹ˆ๋‹ค. ๊ตฌ๋…์ž๋Š” + /// ์ด ์ด๋ฒคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ UI ์š”์†Œ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ฑฐ๋‚˜ ์ƒˆ ์œ„์น˜๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ณ„์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋“ฑ ์นด๋ฉ”๋ผ ์œ„์น˜ ๋ณ€๊ฒฝ์— ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + /// + public event Action OnCameraPositionChanged; + + /// + /// ์นด๋ฉ”๋ผ์˜ ํšŒ์ „์ด ๋ณ€๊ฒฝ๋  ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. + /// + /// ์ด ์ด๋ฒคํŠธ๋Š” ์นด๋ฉ”๋ผ์˜ ํšŒ์ „์ด ์—…๋ฐ์ดํŠธ๋  ๋•Œ๋งˆ๋‹ค ํŠธ๋ฆฌ๊ฑฐ๋ฉ๋‹ˆ๋‹ค. ๊ตฌ๋…์ž๋Š” + /// ์ด ์ด๋ฒคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์นด๋ฉ”๋ผ ๋ฐฉํ–ฅ์˜ ๋ณ€๊ฒฝ์— ์‘๋‹ตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + public event Action OnCameraRotionChanged; + + /// + /// ์ •์˜๋œ ๋ฒ”์œ„ ๋‚ด์—์„œ ์นด๋ฉ”๋ผ์˜ ์ •๊ทœํ™”๋œ ์ˆ˜์ง ์œ„์น˜๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. + /// + /// ๊ฐ’์€ ์นด๋ฉ”๋ผ์˜ ํ˜„์žฌ ์ˆ˜์ง ์œ„์น˜๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ณ„์‚ฐ๋˜๋ฉฐ + /// [0, 1] ๋ฒ”์œ„๋กœ ๊ณ ์ •๋ฉ๋‹ˆ๋‹ค. + public float CameraYRate + { + get + { + // ์นด๋ฉ”๋ผ ๋†’์ด์— ๋”ฐ๋ผ 0~1 ์‚ฌ์ด์˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. + return Mathf.Clamp01((transform.position.y - minCameraY) / (maxCameraY - minCameraY)); + } + } + + private Transform prevTransform; // ์ด์ „ ์นด๋ฉ”๋ผ ๊ฑฐ๋ฆฌ + private Vector3 lastPanPosition; private Vector3 rotationPivot; private bool isRotating = false; + private Coroutine focusCoroutine; // ํ˜„์žฌ ์‹คํ–‰ ์ค‘์ธ ํฌ์ปค์‹ฑ ์ฝ”๋ฃจํ‹ด์„ ์ €์žฅํ•  ๋ณ€์ˆ˜ + void Start() { // ์Šคํฌ๋ฆฝํŠธ ์‹œ์ž‘ ์‹œ, ํšŒ์ „์˜ ๊ธฐ์ค€์ด ๋˜๋Š” ์ค‘์‹ฌ์ ์„ ์นด๋ฉ”๋ผ ์•ž์ชฝ์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค. rotationPivot = transform.position + transform.forward * 10f; + this.prevTransform = transform; // ์ดˆ๊ธฐ ์นด๋ฉ”๋ผ ์œ„์น˜ ์ €์žฅ } + private void StopFocusCoroutine() + { + if (focusCoroutine != null) + { + StopCoroutine(focusCoroutine); + focusCoroutine = null; + } + } + + private void DispatchEvnet() + { + if (prevTransform != null && (prevTransform.position != transform.position || prevTransform.rotation != transform.rotation)) + { + OnCameraChanged?.Invoke(transform); + if(prevTransform.position != transform.position) + { + OnCameraPositionChanged?.Invoke(transform.position); + } + if(prevTransform.rotation != transform.rotation) + { + OnCameraRotionChanged?.Invoke(transform.rotation); + } + } + prevTransform = transform; // ํ˜„์žฌ ์นด๋ฉ”๋ผ ์œ„์น˜ ์ €์žฅ + } + + private void ValidateCameraTransform() + { + // ์นด๋ฉ”๋ผ์˜ ์œ„์น˜๊ฐ€ ์ตœ์†Œ/์ตœ๋Œ€ ๋†’์ด ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜์ง€ ์•Š๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. + Vector3 currentPosition = transform.position; + currentPosition.y = Mathf.Clamp(currentPosition.y, minCameraY, maxCameraY); + transform.position = currentPosition; + ValidateCameraRotation(); + + // ์นด๋ฉ”๋ผ์˜ ์œ„์น˜๊ฐ€ ๋„ˆ๋ฌด ๋ฉ€๋ฆฌ ๋–จ์–ด์ง€์ง€ ์•Š๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. + //float distance = Vector3.Distance(transform.position, rotationPivot); + //if (distance > 100f) // ์˜ˆ์‹œ๋กœ 100f๋ฅผ ์ตœ๋Œ€ ๊ฑฐ๋ฆฌ๋กœ ์„ค์ • + //{ + // transform.position = rotationPivot + (transform.position - rotationPivot).normalized * 100f; + //} + } + + private void ValidateCameraRotation() + { + // ํ˜„์žฌ ํšŒ์ „๊ฐ’์„ ์˜ค์ผ๋Ÿฌ ๊ฐ์œผ๋กœ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. + Vector3 eulerAngles = transform.eulerAngles; + // ์˜ค์ผ๋Ÿฌ ๊ฐ์˜ X์ถ•(Pitch) ๊ฐ’์„ ์ •๊ทœํ™”ํ•˜๊ณ  ์ œํ•œํ•ฉ๋‹ˆ๋‹ค. + // ๊ฐ๋„๊ฐ€ 180๋„๋ฅผ ๋„˜์–ด๊ฐ€๋ฉด ์Œ์ˆ˜ ๊ฐ’์œผ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. (์˜ˆ: 350๋„ -> -10๋„) + float angleX = eulerAngles.x; + if (angleX > 180f) angleX -= 360f; + angleX = Mathf.Clamp(angleX, minPitch, maxPitch); + eulerAngles.x = angleX; + + float angleY = eulerAngles.y; + if (angleY > 180f) angleY -= 360f; + angleY = Mathf.Clamp(angleY, minYaw, maxYaw); + eulerAngles.y = angleY; + + // Z์ถ• ํšŒ์ „(๋กค)์„ 0์œผ๋กœ ์„ค์ •ํ•˜์—ฌ ์นด๋ฉ”๋ผ๊ฐ€ ์˜†์œผ๋กœ ๊ธฐ์šธ์–ด์ง€๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค. + eulerAngles.z = 0f; + + // ์ˆ˜์ •๋œ ์˜ค์ผ๋Ÿฌ ๊ฐ์„ ๋‹ค์‹œ ์ฟผํ„ฐ๋‹ˆ์–ธ์œผ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. + transform.rotation = Quaternion.Euler(eulerAngles); + } + + private Quaternion ValidateRotation(Quaternion rotation) + { + // ํ˜„์žฌ ํšŒ์ „๊ฐ’์„ ์˜ค์ผ๋Ÿฌ ๊ฐ์œผ๋กœ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. + Vector3 eulerAngles = rotation.eulerAngles; + // ์˜ค์ผ๋Ÿฌ ๊ฐ์˜ X์ถ•(Pitch) ๊ฐ’์„ ์ •๊ทœํ™”ํ•˜๊ณ  ์ œํ•œํ•ฉ๋‹ˆ๋‹ค. + // ๊ฐ๋„๊ฐ€ 180๋„๋ฅผ ๋„˜์–ด๊ฐ€๋ฉด ์Œ์ˆ˜ ๊ฐ’์œผ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. (์˜ˆ: 350๋„ -> -10๋„) + float angleX = eulerAngles.x; + if (angleX > 180f) angleX -= 360f; + angleX = Mathf.Clamp(angleX, minPitch, maxPitch); + eulerAngles.x = angleX; + + float angleY = eulerAngles.y; + if (angleY > 180f) angleY -= 360f; + angleY = Mathf.Clamp(angleY, minYaw, maxYaw); + eulerAngles.y = angleY; + + // Z์ถ• ํšŒ์ „(๋กค)์„ 0์œผ๋กœ ์„ค์ •ํ•˜์—ฌ ์นด๋ฉ”๋ผ๊ฐ€ ์˜†์œผ๋กœ ๊ธฐ์šธ์–ด์ง€๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค. + eulerAngles.z = 0f; + + // ์ˆ˜์ •๋œ ์˜ค์ผ๋Ÿฌ ๊ฐ์„ ๋‹ค์‹œ ์ฟผํ„ฐ๋‹ˆ์–ธ์œผ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. + return Quaternion.Euler(eulerAngles); + } + + + // Update ๋Œ€์‹  LateUpdate๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์นด๋ฉ”๋ผ ์›€์ง์ž„์ด ๋‹ค๋ฅธ ๋ชจ๋“  ์—…๋ฐ์ดํŠธ ์ดํ›„์— ์ฒ˜๋ฆฌ๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. // ์ด๋ฅผ ํ†ตํ•ด ์นด๋ฉ”๋ผ์˜ ๋–จ๋ฆผ์ด๋‚˜ ๋Š๊น€ ํ˜„์ƒ์„ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. void LateUpdate() @@ -53,6 +209,7 @@ namespace UVC.Util { if (Input.GetMouseButtonDown(2)) { + StopFocusCoroutine(); lastPanPosition = Input.mousePosition; } @@ -66,11 +223,16 @@ namespace UVC.Util delta = delta.normalized * maxPanDelta; } + // ๋†’์ด์— ๋”ฐ๋ผ ๋™์ ์œผ๋กœ ํŒจ๋‹ ์†๋„ ๊ฒฐ์ •. + float currentPanSpeed = Mathf.Lerp(lowAltitudePanSpeed, highAltitudePanSpeed, CameraYRate); // ํ˜„์žฌ ์นด๋ฉ”๋ผ ๋†’์ด์— ๋”ฐ๋ผ ํŒจ๋‹ ์†๋„๋ฅผ ๋ณด๊ฐ„ํ•ฉ๋‹ˆ๋‹ค. // ์นด๋ฉ”๋ผ์˜ ๋กœ์ปฌ ์ขŒํ‘œ๊ณ„๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ด๋™๋Ÿ‰์„ ๋ณ€ํ™˜ํ•˜์—ฌ ์›”๋“œ ์ขŒํ‘œ๊ณ„์—์„œ ์ด๋™์‹œํ‚ต๋‹ˆ๋‹ค. - transform.Translate(transform.right * -delta.x * panSpeed * Time.deltaTime, Space.World); - transform.Translate(transform.up * -delta.y * panSpeed * Time.deltaTime, Space.World); + transform.Translate(transform.right * -delta.x * currentPanSpeed * Time.deltaTime, Space.World); + transform.Translate(transform.up * -delta.y * currentPanSpeed * Time.deltaTime, Space.World); + + ValidateCameraTransform(); lastPanPosition = Input.mousePosition; + DispatchEvnet(); } } @@ -82,6 +244,7 @@ namespace UVC.Util { if (Input.GetMouseButtonDown(1)) { + StopFocusCoroutine(); isRotating = true; // ๋งˆ์šฐ์Šค ํด๋ฆญ ์ง€์ ์œผ๋กœ Ray๋ฅผ ์ด์„œ ํšŒ์ „์˜ ์ค‘์‹ฌ์ (pivot)์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); @@ -106,6 +269,21 @@ namespace UVC.Util float mouseX = Input.GetAxis("Mouse X") * rotationSpeed * Time.deltaTime; float mouseY = Input.GetAxis("Mouse Y") * rotationSpeed * Time.deltaTime; + // ํ˜„์žฌ X์ถ• ํšŒ์ „ ๊ฐ๋„๋ฅผ ๊ฐ€์ ธ์™€์„œ -180 ~ 180 ๋ฒ”์œ„๋กœ ์ •๊ทœํ™”ํ•ฉ๋‹ˆ๋‹ค. + float currentPitch = transform.eulerAngles.x; + if (currentPitch > 180f) currentPitch -= 360f; + + // ํ˜„์žฌ Y์ถ• ํšŒ์ „ ๊ฐ๋„๋ฅผ ๊ฐ€์ ธ์™€์„œ -180 ~ 180 ๋ฒ”์œ„๋กœ ์ •๊ทœํ™”ํ•ฉ๋‹ˆ๋‹ค. + float currentYaw = transform.eulerAngles.y; + if (currentYaw > 180f) currentYaw -= 360f; + + // ๋งˆ์šฐ์Šค ์ž…๋ ฅ์œผ๋กœ ์ธํ•ด Pitch ๋˜๋Š” Yaw ๊ฐ๋„๊ฐ€ ํ•œ๊ณ„๋ฅผ ๋ฒ—์–ด๋‚˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. + if ((mouseY > 0 && currentPitch >= maxPitch) || (mouseY < 0 && currentPitch <= minPitch) + || (mouseX < 0 && currentYaw >= maxYaw) || (mouseX > 0 && currentYaw <= minYaw)) + { + return; // ํ•œ๊ณ„๋ฅผ ๋„˜์–ด์„œ๋Š” ํšŒ์ „์€ ๋ง‰์Šต๋‹ˆ๋‹ค. + } + // ์ˆ˜ํ‰ ํšŒ์ „์œผ๋กœ ์ธํ•ด ์ˆ˜์ง ํšŒ์ „ ์ถ•(transform.right)์ด ๋ณ€์งˆ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด // ํšŒ์ „ ์ „์˜ right ๋ฒกํ„ฐ๋ฅผ ๋ฏธ๋ฆฌ ์ €์žฅํ•ด ๋‘ก๋‹ˆ๋‹ค. Vector3 verticalRotationAxis = transform.right; @@ -115,6 +293,10 @@ namespace UVC.Util transform.RotateAround(rotationPivot, Vector3.up, -mouseX); // 2. ์ˆ˜์ง ํšŒ์ „ (๋ฏธ๋ฆฌ ์ €์žฅํ•ด ๋‘” ์นด๋ฉ”๋ผ์˜ ์˜ค๋ฅธ์ชฝ ์ถ• ๊ธฐ์ค€) transform.RotateAround(rotationPivot, verticalRotationAxis, mouseY); + + ValidateCameraTransform(); + + DispatchEvnet(); } } @@ -126,6 +308,11 @@ namespace UVC.Util float scroll = Input.GetAxis("Mouse ScrollWheel"); if (scroll != 0f) { + // ํ˜„์žฌ X์ถ• ํšŒ์ „ ๊ฐ๋„๋ฅผ ํ™•์ธํ•˜์—ฌ ํ•œ๊ณ„ ๋ฒ”์œ„ ๋ฐ–์ด๋ฉด ์คŒ์„ ๋ง‰์Šต๋‹ˆ๋‹ค. + float currentPitch = transform.eulerAngles.x; + if (currentPitch > 180f) currentPitch -= 360f; + if (currentPitch < minPitch || currentPitch > maxPitch) return; + Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); Vector3 zoomTarget; @@ -139,9 +326,22 @@ namespace UVC.Util } Vector3 direction = zoomTarget - transform.position; + Vector3 moveVector = direction.normalized * scroll * zoomSpeed; + + // ์นด๋ฉ”๋ผ๊ฐ€ ์•„๋ž˜๋กœ ์›€์ง์ด๋ ค ํ•˜๊ณ (moveVector.y < 0), ์ด๋ฏธ ์ตœ์†Œ ๋†’์ด์— ๋„๋‹ฌํ–ˆ๋‹ค๋ฉด ์ค‘๋‹จํ•ฉ๋‹ˆ๋‹ค. + if (moveVector.y < 0 && transform.position.y <= minCameraY) return; + + // ์นด๋ฉ”๋ผ๊ฐ€ ์œ„๋กœ ์›€์ง์ด๋ ค ํ•˜๊ณ (moveVector.y > 0), ์ด๋ฏธ ์ตœ๋Œ€ ๋†’์ด์— ๋„๋‹ฌํ–ˆ๋‹ค๋ฉด ์ค‘๋‹จํ•ฉ๋‹ˆ๋‹ค. + if (moveVector.y > 0 && transform.position.y >= maxCameraY) return; + + StopFocusCoroutine(); // ์คŒ ์‹คํ–‰ transform.position += direction.normalized * scroll * zoomSpeed; + + ValidateCameraTransform(); + + DispatchEvnet(); } } @@ -149,15 +349,25 @@ namespace UVC.Util /// /// ์ง€์ •๋œ Transform์„ ์ค‘์‹ฌ์œผ๋กœ ์นด๋ฉ”๋ผ๋ฅผ ํฌ์ปค์‹ฑํ•ฉ๋‹ˆ๋‹ค. /// - /// ํฌ์ปค์Šคํ•  ๋Œ€์ƒ์˜ Transform + /// ํฌ์ปค์Šคํ•  ๋Œ€์ƒ์˜ Transform /// ๋Œ€์ƒ๊ณผ์˜ ๊ฑฐ๋ฆฌ - public void FocusOnTargetFast(Transform equipmentTransform, float distance) + public void FocusOnTargetFast(Vector3 equipmentPosition, float distance) { - if (equipmentTransform == null) - return; + if (equipmentPosition == null) return; + + Vector3 position = equipmentPosition; + if (position.y < minCameraY) + { + position.y = minCameraY; // ์ตœ์†Œ ๋†’์ด ์ œํ•œ + } + else if (position.y > maxCameraY) + { + position.y = maxCameraY; // ์ตœ๋Œ€ ๋†’์ด ์ œํ•œ + } + // ์นด๋ฉ”๋ผ๊ฐ€ ๋ฐ”๋ผ๋ณผ ๋Œ€์ƒ์˜ ์ค‘์‹ฌ์  - Vector3 targetPosition = equipmentTransform.position; + Vector3 targetPosition = equipmentPosition; // ํ˜„์žฌ ์นด๋ฉ”๋ผ์˜ ํšŒ์ „๊ฐ์„ ์œ ์ง€ํ•˜๋ฉด์„œ ํƒ€๊ฒŸ์„ ๋ฐ”๋ผ๋ณด๋Š” ๋ฐฉํ–ฅ ์„ค์ • Vector3 directionToTarget = (targetPosition - transform.position).normalized; @@ -171,30 +381,67 @@ namespace UVC.Util // ํšŒ์ „ ํ”ผ๋ด‡ ํฌ์ธํŠธ ์—…๋ฐ์ดํŠธ rotationPivot = targetPosition; + + ValidateCameraTransform(); + + DispatchEvnet(); } /// /// ์ง€์ •๋œ Transform์„ ์ค‘์‹ฌ์œผ๋กœ ์นด๋ฉ”๋ผ๋ฅผ ํฌ์ปค์‹ฑํ•ฉ๋‹ˆ๋‹ค. /// - /// ํฌ์ปค์Šคํ•  ๋Œ€์ƒ์˜ Transform + /// ํฌ์ปค์Šคํ•  ๋Œ€์ƒ์˜ Transform /// ๋Œ€์ƒ๊ณผ์˜ ๊ฑฐ๋ฆฌ /// ์ด๋™์— ๊ฑธ๋ฆฌ๋Š” ์‹œ๊ฐ„(์ดˆ), ๊ธฐ๋ณธ๊ฐ’ 1์ดˆ - public void FocusOnTarget(Transform equipmentTransform, float distance, float duration = 1.0f) + public void FocusOnTarget(Vector3 equipmentPosition, float distance, float duration = 1.0f) { - if (equipmentTransform == null) - return; - + if (equipmentPosition == null) return; + + StopFocusCoroutine(); + + Vector3 position = equipmentPosition; + if(position.y < minCameraY) + { + position.y = minCameraY; // ์ตœ์†Œ ๋†’์ด ์ œํ•œ + } + else if(position.y > maxCameraY) + { + position.y = maxCameraY; // ์ตœ๋Œ€ ๋†’์ด ์ œํ•œ + } + // ์ฝ”๋ฃจํ‹ด์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ถ€๋“œ๋Ÿฌ์šด ์ด๋™ ๊ตฌํ˜„ - StartCoroutine(SmoothFocusOnTarget(equipmentTransform, distance, duration)); + focusCoroutine = StartCoroutine(SmoothFocusOnTarget(position, distance, duration)); } - + + /// + /// ์นด๋ฉ”๋ผ๋ฅผ ์•ž์ชฝ ๋ฐฉํ–ฅ์œผ๋กœ ์ง€์ •๋œ ๊ฑฐ๋ฆฌ๋งŒํผ ๋ฐ”๊นฅ์ชฝ์œผ๋กœ ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค. + /// + /// ์ด ๋ฉ”์„œ๋“œ๋Š” ์ฝ”๋ฃจํ‹ด์„ ์‚ฌ์šฉํ•˜์—ฌ ์นด๋ฉ”๋ผ์˜ ์œ„์น˜๋ฅผ โ€‹โ€‹์•ž์ชฝ ๋ฐฉํ–ฅ์œผ๋กœ ๋ฐ”๊นฅ์ชฝ์œผ๋กœ ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค. + /// ์ „ํ™˜์€ ์ง€์ •๋œ ์‹œ๊ฐ„ ๋™์•ˆ ์ˆ˜ํ–‰๋˜๋ฏ€๋กœ + /// ์‹œ๊ฐ์ ์œผ๋กœ ๋ถ€๋“œ๋Ÿฌ์šด ์›€์ง์ž„์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + /// ์นด๋ฉ”๋ผ๋ฅผ ํ˜„์žฌ ์œ„์น˜์—์„œ ๋ฐ”๊นฅ์ชฝ์œผ๋กœ ์ด๋™ํ•  ๊ฑฐ๋ฆฌ(๋‹จ์œ„)์ž…๋‹ˆ๋‹ค. + /// ์นด๋ฉ”๋ผ ์ „ํ™˜์ด ๋ฐœ์ƒํ•˜๋Š” ์‹œ๊ฐ„(์ดˆ)์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ 1.0์ดˆ์ž…๋‹ˆ๋‹ค. + public void FocusOut(float distance, float duration = 1.0f) + { + + StopFocusCoroutine(); + + // ํ˜„์žฌ ์นด๋ฉ”๋ผ ์œ„์น˜์™€ ํšŒ์ „๊ฐ’์„ ์ €์žฅ + Vector3 startPosition = transform.position; + Quaternion startRotation = transform.rotation; + // ์นด๋ฉ”๋ผ๊ฐ€ ๋ฐ”๋ผ๋ณด๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ์ง€์ •๋œ ๊ฑฐ๋ฆฌ๋งŒํผ ์ด๋™ + Vector3 targetPosition = transform.position + transform.forward * distance; + // ์ฝ”๋ฃจํ‹ด์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ถ€๋“œ๋Ÿฌ์šด ์ด๋™ ๊ตฌํ˜„ + focusCoroutine = StartCoroutine(SmoothFocusOnTarget(targetPosition, distance, duration)); + } + /// /// ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ํƒ€๊ฒŸ๊นŒ์ง€ ์ด๋™ํ•˜๋Š” ์ฝ”๋ฃจํ‹ด /// - private IEnumerator SmoothFocusOnTarget(Transform targetTransform, float distance, float duration) + private IEnumerator SmoothFocusOnTarget(Vector3 targetTransform, float distance, float duration) { // ์นด๋ฉ”๋ผ๊ฐ€ ๋ฐ”๋ผ๋ณผ ๋Œ€์ƒ์˜ ์ค‘์‹ฌ์  - Vector3 targetPosition = targetTransform.position; + Vector3 targetPosition = targetTransform; // ์‹œ์ž‘ ์œ„์น˜์™€ ํšŒ์ „ ์ €์žฅ Vector3 startPosition = transform.position; @@ -206,7 +453,8 @@ namespace UVC.Util // ์ตœ์ข… ํšŒ์ „๊ฐ’ ๊ณ„์‚ฐ Quaternion endRotation = Quaternion.LookRotation(targetPosition - endPosition); - + endRotation = ValidateRotation(endRotation); // ํšŒ์ „๊ฐ’ ๊ฒ€์ฆ ๋ฐ ์ˆ˜์ • + // ์ด๋™ ์‹œ๊ฐ„ ๊ณ„์‚ฐ์„ ์œ„ํ•œ ๋ณ€์ˆ˜ float elapsedTime = 0f; @@ -221,7 +469,9 @@ namespace UVC.Util // ์œ„์น˜์™€ ํšŒ์ „ ๋ณด๊ฐ„ transform.position = Vector3.Lerp(startPosition, endPosition, smoothT); transform.rotation = Quaternion.Slerp(startRotation, endRotation, smoothT); - + + ValidateCameraTransform(); + yield return null; } @@ -231,6 +481,11 @@ namespace UVC.Util // ํšŒ์ „ ํ”ผ๋ด‡ ํฌ์ธํŠธ ์—…๋ฐ์ดํŠธ rotationPivot = targetPosition; + + ValidateCameraTransform(); + + DispatchEvnet(); + focusCoroutine = null; // ์ฝ”๋ฃจํ‹ด ์™„๋ฃŒ ํ›„ ์ฐธ์กฐ๋ฅผ null๋กœ ์„ค์ • } /// @@ -240,5 +495,9 @@ namespace UVC.Util { return t < 0.5f ? 4f * t * t * t : 1f - Mathf.Pow(-2f * t + 2f, 3f) / 2f; } + + + + } }