From 08cd464393e128c3add78e74be21ec243a9f2d69 Mon Sep 17 00:00:00 2001 From: logonkhi Date: Wed, 2 Jul 2025 18:24:00 +0900 Subject: [PATCH] =?UTF-8?q?=EC=95=8C=EB=9E=8C=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Resources/Prefabs/UI/Factory/Alarm.prefab | 16 +- ...larmIcon.prefab => AlarmSingleIcon.prefab} | 2 +- ...refab.meta => AlarmSingleIcon.prefab.meta} | 0 .../Prefabs/UI/Factory/InfoWindow.prefab | 4 +- .../Resources/Prefabs/UI/Modal/Toast.prefab | 361 ++++++++++++++++++ .../Prefabs/UI/Modal/Toast.prefab.meta | 7 + Assets/Scenes/SampleProject.unity | 10 +- .../Scripts/UVC/Factory/Alarm/AlarmManager.cs | 67 +++- ...{SingleAlarmIcon.cs => AlarmSingleIcon.cs} | 2 +- ...rmIcon.cs.meta => AlarmSingleIcon.cs.meta} | 0 .../UVC/Factory/Alarm/AlarmUIController.cs | 20 +- .../UVC/{UI/Info.meta => Factory/Camera.meta} | 2 +- .../Camera}/CameraController.cs | 37 +- .../Camera}/CameraController.cs.meta | 0 .../UVC/Factory/Component/FactoryObject.cs | 2 +- Assets/Scripts/UVC/Factory/Modal.meta | 8 + .../{UI/Info => Factory/Modal}/InfoWindow.cs | 13 +- .../Info => Factory/Modal}/InfoWindow.cs.meta | 0 Assets/Scripts/UVC/UI/Modal/Toast.cs | 115 ++++++ Assets/Scripts/UVC/UI/Modal/Toast.cs.meta | 2 + ProjectSettings/TagManager.asset | 31 +- 21 files changed, 611 insertions(+), 88 deletions(-) rename Assets/Resources/Prefabs/UI/Factory/{AlarmIcon.prefab => AlarmSingleIcon.prefab} (99%) rename Assets/Resources/Prefabs/UI/Factory/{AlarmIcon.prefab.meta => AlarmSingleIcon.prefab.meta} (100%) create mode 100644 Assets/Resources/Prefabs/UI/Modal/Toast.prefab create mode 100644 Assets/Resources/Prefabs/UI/Modal/Toast.prefab.meta rename Assets/Scripts/UVC/Factory/Alarm/{SingleAlarmIcon.cs => AlarmSingleIcon.cs} (96%) rename Assets/Scripts/UVC/Factory/Alarm/{SingleAlarmIcon.cs.meta => AlarmSingleIcon.cs.meta} (100%) rename Assets/Scripts/UVC/{UI/Info.meta => Factory/Camera.meta} (77%) rename Assets/Scripts/UVC/{Util => Factory/Camera}/CameraController.cs (97%) rename Assets/Scripts/UVC/{Util => Factory/Camera}/CameraController.cs.meta (100%) create mode 100644 Assets/Scripts/UVC/Factory/Modal.meta rename Assets/Scripts/UVC/{UI/Info => Factory/Modal}/InfoWindow.cs (95%) rename Assets/Scripts/UVC/{UI/Info => Factory/Modal}/InfoWindow.cs.meta (100%) create mode 100644 Assets/Scripts/UVC/UI/Modal/Toast.cs create mode 100644 Assets/Scripts/UVC/UI/Modal/Toast.cs.meta diff --git a/Assets/Resources/Prefabs/UI/Factory/Alarm.prefab b/Assets/Resources/Prefabs/UI/Factory/Alarm.prefab index bd80de08..67202aec 100644 --- a/Assets/Resources/Prefabs/UI/Factory/Alarm.prefab +++ b/Assets/Resources/Prefabs/UI/Factory/Alarm.prefab @@ -67,8 +67,8 @@ MonoBehaviour: 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_fontAsset: {fileID: 11400000, guid: 2c77cc500db5adc499bfa50030f7e8c2, type: 2} + m_sharedMaterial: {fileID: -8159279640617175905, guid: 2c77cc500db5adc499bfa50030f7e8c2, type: 2} m_fontSharedMaterials: [] m_fontMaterial: {fileID: 0} m_fontMaterials: [] @@ -92,13 +92,13 @@ MonoBehaviour: m_faceColor: serializedVersion: 2 rgba: 4294967295 - m_fontSize: 12 - m_fontSizeBase: 12 + m_fontSize: 16 + m_fontSizeBase: 16 m_fontWeight: 400 m_enableAutoSizing: 0 m_fontSizeMin: 18 m_fontSizeMax: 72 - m_fontStyle: 0 + m_fontStyle: 1 m_HorizontalAlignment: 2 m_VerticalAlignment: 512 m_textAlignment: 65535 @@ -211,7 +211,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: 100} + m_SizeDelta: {x: 30, y: 30} m_Pivot: {x: 0.5, y: 0.5} --- !u!114 &5380681345511526047 MonoBehaviour: @@ -228,7 +228,7 @@ MonoBehaviour: clusterView: {fileID: 4918696741701580718} alarmCountText: {fileID: 8650239058674280921} expandedView: {fileID: 952545100964675415} - singleAlarmIconPrefab: {fileID: 7314511769243682470, guid: e9acc8c9a93a2b5409fc01661660b217, type: 3} + alarmSingleIconPrefab: {fileID: 7314511769243682470, guid: e9acc8c9a93a2b5409fc01661660b217, type: 3} --- !u!1 &1960784422133791095 GameObject: m_ObjectHideFlags: 0 @@ -264,7 +264,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: -10, y: -10} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &4629718865595954553 CanvasRenderer: diff --git a/Assets/Resources/Prefabs/UI/Factory/AlarmIcon.prefab b/Assets/Resources/Prefabs/UI/Factory/AlarmSingleIcon.prefab similarity index 99% rename from Assets/Resources/Prefabs/UI/Factory/AlarmIcon.prefab rename to Assets/Resources/Prefabs/UI/Factory/AlarmSingleIcon.prefab index e8d9fac3..4ae6fb41 100644 --- a/Assets/Resources/Prefabs/UI/Factory/AlarmIcon.prefab +++ b/Assets/Resources/Prefabs/UI/Factory/AlarmSingleIcon.prefab @@ -222,7 +222,7 @@ GameObject: - component: {fileID: 3374630250525829090} - component: {fileID: 5545478218830425297} m_Layer: 5 - m_Name: AlarmIcon + m_Name: AlarmSingleIcon m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 diff --git a/Assets/Resources/Prefabs/UI/Factory/AlarmIcon.prefab.meta b/Assets/Resources/Prefabs/UI/Factory/AlarmSingleIcon.prefab.meta similarity index 100% rename from Assets/Resources/Prefabs/UI/Factory/AlarmIcon.prefab.meta rename to Assets/Resources/Prefabs/UI/Factory/AlarmSingleIcon.prefab.meta diff --git a/Assets/Resources/Prefabs/UI/Factory/InfoWindow.prefab b/Assets/Resources/Prefabs/UI/Factory/InfoWindow.prefab index c2cb37bb..23735351 100644 --- a/Assets/Resources/Prefabs/UI/Factory/InfoWindow.prefab +++ b/Assets/Resources/Prefabs/UI/Factory/InfoWindow.prefab @@ -414,7 +414,7 @@ GameObject: m_Component: - component: {fileID: 4802890858156259540} - component: {fileID: 7623125061856383678} - - component: {fileID: 3914245719037572856} + - component: {fileID: 9096332282778631911} m_Layer: 5 m_Name: InfoWindow m_TagString: Untagged @@ -454,7 +454,7 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 4907041631117111019} m_CullTransparentMesh: 1 ---- !u!114 &3914245719037572856 +--- !u!114 &9096332282778631911 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} diff --git a/Assets/Resources/Prefabs/UI/Modal/Toast.prefab b/Assets/Resources/Prefabs/UI/Modal/Toast.prefab new file mode 100644 index 00000000..6561f1fb --- /dev/null +++ b/Assets/Resources/Prefabs/UI/Modal/Toast.prefab @@ -0,0 +1,361 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &484408238305816480 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2593443939925335852} + - component: {fileID: 1256423686318590861} + - component: {fileID: 6612431241575804293} + - component: {fileID: 8927325362145620876} + m_Layer: 5 + m_Name: Toast + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2593443939925335852 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 484408238305816480} + 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: 4669456136788485616} + - {fileID: 5324354243570083418} + - {fileID: 5363215964879729180} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 0.5, y: 0} + m_AnchoredPosition: {x: 0, y: 50} + m_SizeDelta: {x: 100, y: 40} + m_Pivot: {x: 0.5, y: 0} +--- !u!114 &1256423686318590861 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 484408238305816480} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d007f3f774d241a44a69d7349dd7c464, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!222 &6612431241575804293 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 484408238305816480} + m_CullTransparentMesh: 1 +--- !u!225 &8927325362145620876 +CanvasGroup: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 484408238305816480} + m_Enabled: 1 + m_Alpha: 1 + m_Interactable: 1 + m_BlocksRaycasts: 1 + m_IgnoreParentGroups: 0 +--- !u!1 &756064823853878307 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4669456136788485616} + - component: {fileID: 3254108561654149228} + - component: {fileID: 4970594764271747280} + m_Layer: 5 + m_Name: shadow + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &4669456136788485616 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 756064823853878307} + 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: 2593443939925335852} + 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 &3254108561654149228 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 756064823853878307} + m_CullTransparentMesh: 1 +--- !u!114 &4970594764271747280 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 756064823853878307} + 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: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 0 + 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 &2613469246520695834 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5363215964879729180} + - component: {fileID: 3159460824223373132} + - component: {fileID: 7535797121015972946} + 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 &5363215964879729180 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2613469246520695834} + 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: 2593443939925335852} + 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: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &3159460824223373132 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2613469246520695834} + m_CullTransparentMesh: 1 +--- !u!114 &7535797121015972946 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2613469246520695834} + 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: "message \uBA54\uC138\uC9C0" + 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: 14 + m_fontSizeBase: 14 + 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: -2 + m_lineSpacing: -14 + 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: 1 + 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 &6035955017215134893 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5324354243570083418} + - component: {fileID: 7046310248760442982} + - component: {fileID: 5513919840077118301} + m_Layer: 5 + m_Name: bg + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5324354243570083418 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6035955017215134893} + 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: 2593443939925335852} + 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 &7046310248760442982 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6035955017215134893} + m_CullTransparentMesh: 1 +--- !u!114 &5513919840077118301 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6035955017215134893} + 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.18867922, g: 0.18867922, b: 0.18867922, 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 diff --git a/Assets/Resources/Prefabs/UI/Modal/Toast.prefab.meta b/Assets/Resources/Prefabs/UI/Modal/Toast.prefab.meta new file mode 100644 index 00000000..f3100f9f --- /dev/null +++ b/Assets/Resources/Prefabs/UI/Modal/Toast.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 2dc1a48f64b974f4fbd11a5240c18107 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scenes/SampleProject.unity b/Assets/Scenes/SampleProject.unity index 038e71cc..da83b3f3 100644 --- a/Assets/Scenes/SampleProject.unity +++ b/Assets/Scenes/SampleProject.unity @@ -442,6 +442,10 @@ MonoBehaviour: maxPanDelta: 50 minCameraY: 2 maxCameraY: 50 + minPitch: 20 + maxPitch: 85 + minYaw: -45 + maxYaw: 45 --- !u!1 &410087039 GameObject: m_ObjectHideFlags: 0 @@ -577,7 +581,7 @@ GameObject: - component: {fileID: 483439348} m_Layer: 5 m_Name: StaticCanvas - m_TagString: Untagged + m_TagString: StaticCanvas m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 @@ -683,7 +687,7 @@ GameObject: - component: {fileID: 495653795} m_Layer: 5 m_Name: ModalCanvas - m_TagString: Untagged + m_TagString: ModalCanvas m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 @@ -1981,7 +1985,7 @@ GameObject: - component: {fileID: 2030316709} m_Layer: 5 m_Name: DynamicCanvas - m_TagString: Untagged + m_TagString: DynamicCanvas m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 diff --git a/Assets/Scripts/UVC/Factory/Alarm/AlarmManager.cs b/Assets/Scripts/UVC/Factory/Alarm/AlarmManager.cs index 8f233fd2..fcb91a60 100644 --- a/Assets/Scripts/UVC/Factory/Alarm/AlarmManager.cs +++ b/Assets/Scripts/UVC/Factory/Alarm/AlarmManager.cs @@ -44,7 +44,8 @@ namespace UVC.Factory.Alarm //알람 데이터가 AGV와 관련 없는것이 많아서, AGV 이름을 미리 정의합니다. for (int i = 1; i <= 115; i++) { - agvNames.Add($"HFF09CNA8{i.ToString("D3")}"); + //agvNames.Add($"HFF09CNA8{i.ToString("D3")}"); + agvNames.Add($"HFF09CNA8061"); } } @@ -186,17 +187,35 @@ namespace UVC.Factory.Alarm return; } - // 없으면 새로 생성 - FactoryObject? targetObject = dataManager!.FindByName(data.GetString("TRANSPORT_EQP_ID")!); - Debug.Log($"AlarmManager {targetObject==null} {data.Id}, {data.GetString("TRANSPORT_EQP_ID")}"); - if (targetObject != null) + + string? eqpId = data.GetString("TRANSPORT_EQP_ID"); + if (eqpId == null) return; + + FactoryObject? targetObject = dataManager!.FindByName(eqpId); + Debug.Log($"AlarmManager {targetObject==null} {data.Id}, {eqpId}"); + if (targetObject == null) return; + + if (activeAlarmUIs.ContainsKey(eqpId)) { + if(activeAlarmUIs[eqpId].ContainsAlarm(data)) + { + activeAlarmUIs[eqpId].UpdateAlarm(data); + } + else + { + activeAlarmUIs[eqpId].AddAlarm(data); + } + } + else + { + // 없으면 새로 생성 GameObject newUIObject = Instantiate(alarmUIPrefab, transform); // 매니저 하위에 생성 AlarmUIController newUiController = newUIObject.GetComponent(); newUiController.Initialize(targetObject, data); - activeAlarmUIs.Add(data.Id!, newUiController); + activeAlarmUIs.Add(eqpId, newUiController); } + } @@ -207,11 +226,22 @@ namespace UVC.Factory.Alarm Debug.LogError($"Modify Alarm Received No data. {data}"); return; } + string? eqpId = data.GetString("TRANSPORT_EQP_ID"); + if (eqpId == null) return; + // 이미 해당 설비에 알람 UI가 떠 있는지 확인 - if (activeAlarmUIs.TryGetValue(data.Id!, out AlarmUIController uiController)) + if (activeAlarmUIs.TryGetValue(eqpId, out AlarmUIController uiController)) { - // 있으면 기존 UI에 알람 정보만 추가 - uiController.UpdateAlarm(data); + // 있으면 기존 UI에 알람 정보 업데이트 + if (uiController.ContainsAlarm(data)) + { + uiController.UpdateAlarm(data); + } + else + { + // 없으면 새로 추가 + uiController.AddAlarm(data); + } } } @@ -222,13 +252,22 @@ namespace UVC.Factory.Alarm Debug.LogError($"Clear Alarm Received No data. {data}"); return; } - if (activeAlarmUIs.TryGetValue(data.Id!, out AlarmUIController uiController)) + + string? eqpId = data.GetString("TRANSPORT_EQP_ID"); + if (eqpId == null) return; + + if (activeAlarmUIs.TryGetValue(eqpId, out AlarmUIController uiController)) { - uiController.RemoveAlarm(data); - if (uiController.GetAlarmCount() == 0) + // 있으면 기존 UI에 알람 정보 업데이트 + if (uiController.ContainsAlarm(data)) { - activeAlarmUIs.Remove(data.Id!); - Destroy(uiController.gameObject); + uiController.RemoveAlarm(data); + + if (uiController.GetAlarmCount() == 0) + { + activeAlarmUIs.Remove(data.Id!); + Destroy(uiController.gameObject); + } } } } diff --git a/Assets/Scripts/UVC/Factory/Alarm/SingleAlarmIcon.cs b/Assets/Scripts/UVC/Factory/Alarm/AlarmSingleIcon.cs similarity index 96% rename from Assets/Scripts/UVC/Factory/Alarm/SingleAlarmIcon.cs rename to Assets/Scripts/UVC/Factory/Alarm/AlarmSingleIcon.cs index 1841bf79..126a03e6 100644 --- a/Assets/Scripts/UVC/Factory/Alarm/SingleAlarmIcon.cs +++ b/Assets/Scripts/UVC/Factory/Alarm/AlarmSingleIcon.cs @@ -5,7 +5,7 @@ using UVC.Util; namespace UVC.Factory.Alarm { - public class SingleAlarmIcon : MonoBehaviour + public class AlarmSingleIcon : MonoBehaviour { [Tooltip("알람 내용을 표시하는 텍스트입니다.")] diff --git a/Assets/Scripts/UVC/Factory/Alarm/SingleAlarmIcon.cs.meta b/Assets/Scripts/UVC/Factory/Alarm/AlarmSingleIcon.cs.meta similarity index 100% rename from Assets/Scripts/UVC/Factory/Alarm/SingleAlarmIcon.cs.meta rename to Assets/Scripts/UVC/Factory/Alarm/AlarmSingleIcon.cs.meta diff --git a/Assets/Scripts/UVC/Factory/Alarm/AlarmUIController.cs b/Assets/Scripts/UVC/Factory/Alarm/AlarmUIController.cs index c98a8d1f..314a8323 100644 --- a/Assets/Scripts/UVC/Factory/Alarm/AlarmUIController.cs +++ b/Assets/Scripts/UVC/Factory/Alarm/AlarmUIController.cs @@ -18,12 +18,12 @@ namespace UVC.Factory.Alarm [Tooltip("확장된 알람 뷰입니다. 개별 알람 아이콘을 표시합니다.")] [SerializeField] private GameObject expandedView; [Tooltip("개별 알람 아이콘 프리팹입니다. 이 프리팹은 개별 알람 정보를 표시하는 UI 요소를 포함해야 합니다.")] - [SerializeField] private GameObject singleAlarmIconPrefab; // 개별 알람 아이콘 + [SerializeField] private GameObject alarmSingleIconPrefab; // 개별 알람 아이콘 private Transform targetObject; private List alarms = new List(); private bool isExpanded = false; - private SingleAlarmIcon singleAlarmIcon1 = null; + private AlarmSingleIcon singleAlarmIcon1 = null; private RectTransform rectTransform; private Canvas mainCanvas; @@ -99,6 +99,11 @@ namespace UVC.Factory.Alarm } } + public bool ContainsAlarm(DataObject alarm) + { + return alarms.Exists(a => a.Id == alarm.Id); + } + public void AddAlarm(DataObject alarm) { alarms.Add(alarm); @@ -156,7 +161,7 @@ namespace UVC.Factory.Alarm // 여기에 단일 알람 아이콘을 보여주는 로직 추가 if (singleAlarmIcon1 == null) { - singleAlarmIcon1 = Instantiate(singleAlarmIconPrefab, transform).GetComponent(); + singleAlarmIcon1 = Instantiate(alarmSingleIconPrefab, transform).GetComponent(); } singleAlarmIcon1.gameObject.SetActive(true); singleAlarmIcon1.SetData(alarms[0], targetObject); @@ -205,16 +210,17 @@ namespace UVC.Factory.Alarm } // 원형으로 아이콘 배치 - float radius = 100.0f; // Canvas 좌표계에 맞는 반지름 값 + float radius = (alarms.Count - 1) * 20.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) * radius; - GameObject iconObj = Instantiate(singleAlarmIconPrefab, expandedView.transform); + GameObject iconObj = Instantiate(alarmSingleIconPrefab, expandedView.transform); iconObj.transform.localPosition = pos; - // iconObj의 SingleAlarmIcon 스크립트에 알람 데이터 전달 - iconObj.GetComponent().SetData(alarms[i], targetObject); + // iconObj의 AlarmSingleIcon 스크립트에 알람 데이터 전달 + iconObj.GetComponent().SetData(alarms[i], targetObject); } //AnimateUISpace(0f); // 간격을 0으로 애니메이션 diff --git a/Assets/Scripts/UVC/UI/Info.meta b/Assets/Scripts/UVC/Factory/Camera.meta similarity index 77% rename from Assets/Scripts/UVC/UI/Info.meta rename to Assets/Scripts/UVC/Factory/Camera.meta index df7a6635..c4d21870 100644 --- a/Assets/Scripts/UVC/UI/Info.meta +++ b/Assets/Scripts/UVC/Factory/Camera.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 8822a5b71db85f64483ede945af84867 +guid: ef255ae14c2a7a647ab9e652029763b2 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/Scripts/UVC/Util/CameraController.cs b/Assets/Scripts/UVC/Factory/Camera/CameraController.cs similarity index 97% rename from Assets/Scripts/UVC/Util/CameraController.cs rename to Assets/Scripts/UVC/Factory/Camera/CameraController.cs index 4dc6ddac..de143846 100644 --- a/Assets/Scripts/UVC/Util/CameraController.cs +++ b/Assets/Scripts/UVC/Factory/Camera/CameraController.cs @@ -1,10 +1,9 @@ using System; using System.Collections; using UnityEngine; -using UnityEngine.UIElements; using UVC.Core; -namespace UVC.Util +namespace UVC.Factory { /// /// 마우스 입력에 따라 카메라를 이동, 회전, 줌하는 컨트롤러입니다. @@ -116,15 +115,15 @@ namespace UVC.Util if (prevTransform != null && (prevTransform.position != transform.position || prevTransform.rotation != transform.rotation)) { OnCameraChanged?.Invoke(transform); - if(prevTransform.position != transform.position) + if (prevTransform.position != transform.position) { OnCameraPositionChanged?.Invoke(transform.position); } - if(prevTransform.rotation != transform.rotation) + if (prevTransform.rotation != transform.rotation) { OnCameraRotionChanged?.Invoke(transform.rotation); } - } + } prevTransform = transform; // 현재 카메라 위치 저장 } @@ -312,7 +311,7 @@ namespace UVC.Util 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; @@ -364,7 +363,7 @@ namespace UVC.Util { position.y = maxCameraY; // 최대 높이 제한 } - + // 카메라가 바라볼 대상의 중심점 Vector3 targetPosition = equipmentPosition; @@ -400,11 +399,11 @@ namespace UVC.Util StopFocusCoroutine(); Vector3 position = equipmentPosition; - if(position.y < minCameraY) + if (position.y < minCameraY) { position.y = minCameraY; // 최소 높이 제한 } - else if(position.y > maxCameraY) + else if (position.y > maxCameraY) { position.y = maxCameraY; // 최대 높이 제한 } @@ -442,30 +441,30 @@ namespace UVC.Util { // 카메라가 바라볼 대상의 중심점 Vector3 targetPosition = targetTransform; - + // 시작 위치와 회전 저장 Vector3 startPosition = transform.position; Quaternion startRotation = transform.rotation; - + // 타겟을 보는 최종 위치와 회전 계산 Vector3 directionToTarget = (targetPosition - startPosition).normalized; Vector3 endPosition = targetPosition - directionToTarget * distance; - + // 최종 회전값 계산 Quaternion endRotation = Quaternion.LookRotation(targetPosition - endPosition); endRotation = ValidateRotation(endRotation); // 회전값 검증 및 수정 // 이동 시간 계산을 위한 변수 float elapsedTime = 0f; - + while (elapsedTime < duration) { elapsedTime += Time.deltaTime; float t = Mathf.Clamp01(elapsedTime / duration); - + // 부드러운 이동을 위한 Easing 함수 적용 float smoothT = EaseInOutCubic(t); - + // 위치와 회전 보간 transform.position = Vector3.Lerp(startPosition, endPosition, smoothT); transform.rotation = Quaternion.Slerp(startRotation, endRotation, smoothT); @@ -474,11 +473,11 @@ namespace UVC.Util yield return null; } - + // 정확한 최종 위치와 회전 설정 transform.position = endPosition; transform.LookAt(targetPosition); - + // 회전 피봇 포인트 업데이트 rotationPivot = targetPosition; @@ -487,7 +486,7 @@ namespace UVC.Util DispatchEvnet(); focusCoroutine = null; // 코루틴 완료 후 참조를 null로 설정 } - + /// /// Cubic ease-in/out 함수로 부드러운 이동 효과를 줍니다. /// @@ -497,7 +496,7 @@ namespace UVC.Util } - + } } diff --git a/Assets/Scripts/UVC/Util/CameraController.cs.meta b/Assets/Scripts/UVC/Factory/Camera/CameraController.cs.meta similarity index 100% rename from Assets/Scripts/UVC/Util/CameraController.cs.meta rename to Assets/Scripts/UVC/Factory/Camera/CameraController.cs.meta diff --git a/Assets/Scripts/UVC/Factory/Component/FactoryObject.cs b/Assets/Scripts/UVC/Factory/Component/FactoryObject.cs index d7acc9cc..d57c3056 100644 --- a/Assets/Scripts/UVC/Factory/Component/FactoryObject.cs +++ b/Assets/Scripts/UVC/Factory/Component/FactoryObject.cs @@ -3,8 +3,8 @@ using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using UVC.Data; +using UVC.Factory.Modal; using UVC.Object3d; -using UVC.UI.Info; namespace UVC.Factory.Component { diff --git a/Assets/Scripts/UVC/Factory/Modal.meta b/Assets/Scripts/UVC/Factory/Modal.meta new file mode 100644 index 00000000..ef7f2dbd --- /dev/null +++ b/Assets/Scripts/UVC/Factory/Modal.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 331531bab0bc0974c89e2eb1560a5043 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UVC/UI/Info/InfoWindow.cs b/Assets/Scripts/UVC/Factory/Modal/InfoWindow.cs similarity index 95% rename from Assets/Scripts/UVC/UI/Info/InfoWindow.cs rename to Assets/Scripts/UVC/Factory/Modal/InfoWindow.cs index b3ba6658..486a023a 100644 --- a/Assets/Scripts/UVC/UI/Info/InfoWindow.cs +++ b/Assets/Scripts/UVC/Factory/Modal/InfoWindow.cs @@ -1,13 +1,13 @@ #nullable enable -using System; using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.UI; using UVC.Core; +using UVC.UI.Modal; -namespace UVC.UI.Info +namespace UVC.Factory.Modal { /// /// 3D 객체를 따라다니며 정보를 표시하는 UI 창입니다. @@ -64,7 +64,7 @@ namespace UVC.UI.Info { copyButton.onClick.AddListener(CopyToClipboard); } - + // 처음에는 정보 창을 숨깁니다. if (gameObject.activeSelf) @@ -79,6 +79,7 @@ namespace UVC.UI.Info if (!string.IsNullOrEmpty(message)) { GUIUtility.systemCopyBuffer = message; + Toast.Show("정보가 클립보드에 복사되었습니다.", 2f, 0.5f); } } @@ -137,7 +138,7 @@ namespace UVC.UI.Info rectTransform.localPosition = new Vector3(localPoint.x, localPoint.y, rectTransform.localPosition.z); } } - + // UI가 항상 보이도록 카메라를 향하게 설정 (World Space Canvas인 경우에만 필요) Canvas parentCanvas = GetComponentInParent(); @@ -171,15 +172,17 @@ namespace UVC.UI.Info if (target == null) return; if (text != null) { + message = string.Empty; string combinedString = string.Empty; foreach (var kvp in information) { // 태그를 사용하여 줄바꿈 시에도 정렬이 유지되도록 합니다. combinedString += $"{kvp.Key}{kvp.Value ?? "null"}\n"; + message += $"{kvp.Key}: {kvp.Value ?? "null"}\n"; // 메시지에 추가 } combinedString = combinedString.TrimEnd('\n'); // 마지막 줄바꿈 제거 + message = message.TrimEnd('\n'); // 마지막 줄바꿈 제거 text.text = combinedString; - message = combinedString; } // size를 text에 맞게 조정합니다. RectTransform? rect = GetComponent(); diff --git a/Assets/Scripts/UVC/UI/Info/InfoWindow.cs.meta b/Assets/Scripts/UVC/Factory/Modal/InfoWindow.cs.meta similarity index 100% rename from Assets/Scripts/UVC/UI/Info/InfoWindow.cs.meta rename to Assets/Scripts/UVC/Factory/Modal/InfoWindow.cs.meta diff --git a/Assets/Scripts/UVC/UI/Modal/Toast.cs b/Assets/Scripts/UVC/UI/Modal/Toast.cs new file mode 100644 index 00000000..a8db1ed7 --- /dev/null +++ b/Assets/Scripts/UVC/UI/Modal/Toast.cs @@ -0,0 +1,115 @@ +using System.Collections; +using TMPro; +using UnityEngine; +using UVC.Core; + +namespace UVC.UI.Modal +{ + public class Toast : SingletonApp + { + protected static string prefabPath = "Prefabs/UI/Modal/Toast"; + protected static GameObject prefab; + protected static Toast toast; + + + public static void Show(string message, float duration = 3f, float fadeInOutTime = 0.25f) + { + if (prefab == null) prefab = Resources.Load(prefabPath, typeof(GameObject)) as GameObject; + if (prefab != null && toast == null) + { + GameObject go = UnityEngine.Object.Instantiate(prefab); + toast = go.GetComponent(); + toast.change(0); + } + if (toast != null) + { + toast.gameObject.SetActive(true); + var canvass = GameObject.FindObjectsByType(FindObjectsSortMode.None); + Canvas canvas = null; + foreach (var c in canvass) + { + if (c.tag == "ModalCanvas") + { + canvas = c; + toast.transform.SetParent(canvas.transform); + toast.show(message, duration, fadeInOutTime); + break; + } + } + } + } + + protected CanvasGroup canvasGroup; + protected TextMeshProUGUI txt; + + protected void show(string message, float duration = 3, float fadeInOutTime = 0.25f) + { + StopAllCoroutines(); + StartCoroutine(showCoroutine(message, duration, fadeInOutTime)); + } + + protected IEnumerator showCoroutine(string message, float duration = 3, float fadeInOutTime = 0.25f) + { + if (txt == null) txt = GetComponentInChildren(); + fitTextWidth(GetComponent(), txt, message); + + yield return fadeInOut(fadeInOutTime, true); + change(1); + float elapsedTime = 0.0f; + while (elapsedTime < duration) + { + elapsedTime += Time.deltaTime; + yield return null; + } + + yield return fadeInOut(fadeInOutTime, false); + change(0); + transform.SetParent(null); + gameObject.SetActive(true); + } + + + protected IEnumerator fadeInOut(float durationTime, bool inOut) + { + float start = 0.0f; + float end = 1.0f; + if (!inOut) + { + start = 1.0f; + end = 0.0f; + } + + float elapsedTime = 0.0f; + + while (elapsedTime < durationTime) + { + float alpha = Mathf.Lerp(start, end, elapsedTime / durationTime); + + change(alpha); + + elapsedTime += Time.deltaTime; + + yield return null; + } + } + + protected void change(float alpha) + { + if (canvasGroup == null) canvasGroup = GetComponent(); + canvasGroup.alpha = alpha; + } + + private void fitTextWidth(RectTransform rect, TextMeshProUGUI text, string textValue) + { + text.text = textValue; + + Vector2 rectSize = rect.sizeDelta; + rectSize.x = text.preferredWidth + 20; + rect.sizeDelta = rectSize; + rect.anchoredPosition = new Vector2(0, rectSize.y + 10); + + + } + + } +} diff --git a/Assets/Scripts/UVC/UI/Modal/Toast.cs.meta b/Assets/Scripts/UVC/UI/Modal/Toast.cs.meta new file mode 100644 index 00000000..173fa4c1 --- /dev/null +++ b/Assets/Scripts/UVC/UI/Modal/Toast.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: d007f3f774d241a44a69d7349dd7c464 \ No newline at end of file diff --git a/ProjectSettings/TagManager.asset b/ProjectSettings/TagManager.asset index 6413d11f..ba4f3e51 100644 --- a/ProjectSettings/TagManager.asset +++ b/ProjectSettings/TagManager.asset @@ -2,8 +2,11 @@ %TAG !u! tag:unity3d.com,2011: --- !u!78 &1 TagManager: - serializedVersion: 2 - tags: [] + serializedVersion: 3 + tags: + - ModalCanvas + - StaticCanvas + - DynamicCanvas layers: - Default - TransparentFX @@ -50,27 +53,3 @@ TagManager: - Light Layer 5 - Light Layer 6 - Light Layer 7 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -