ui 생성 로직 변경
This commit is contained in:
parent
0dc138ea2f
commit
ac49d77573
@ -134,4 +134,5 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 11500000, guid: 41f0ee0aabb2f954d918caa8d484f646, type: 3}
|
m_Script: {fileID: 11500000, guid: 41f0ee0aabb2f954d918caa8d484f646, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
|
<UiType>k__BackingField: 4
|
||||||
_enableBlockImage: 1
|
_enableBlockImage: 1
|
||||||
|
@ -319,5 +319,6 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 11500000, guid: 828648aab79941544bf8ceb7b25b586c, type: 3}
|
m_Script: {fileID: 11500000, guid: 828648aab79941544bf8ceb7b25b586c, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
|
<UiType>k__BackingField: 4
|
||||||
_enableBlockImage: 0
|
_enableBlockImage: 0
|
||||||
_messageText: {fileID: 1263817835881307751}
|
_messageText: {fileID: 1263817835881307751}
|
||||||
|
@ -422,6 +422,7 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 11500000, guid: eccb2d58803b65f4e82f22153315d3c6, type: 3}
|
m_Script: {fileID: 11500000, guid: eccb2d58803b65f4e82f22153315d3c6, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
|
<UiType>k__BackingField: 2
|
||||||
_enableBlockImage: 0
|
_enableBlockImage: 0
|
||||||
_filledImage: {fileID: 1182510989530764005}
|
_filledImage: {fileID: 1182510989530764005}
|
||||||
_textLabel: {fileID: 5874059589008679693}
|
_textLabel: {fileID: 5874059589008679693}
|
||||||
|
@ -651,7 +651,7 @@ PrefabInstance:
|
|||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 6952779389930089995, guid: 4f2bf029cb06b084ba41defc8fc76731, type: 3}
|
- target: {fileID: 6952779389930089995, guid: 4f2bf029cb06b084ba41defc8fc76731, type: 3}
|
||||||
propertyPath: m_Name
|
propertyPath: m_Name
|
||||||
value: Hud
|
value: RestaurantHud
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
m_RemovedComponents: []
|
m_RemovedComponents: []
|
||||||
m_RemovedGameObjects:
|
m_RemovedGameObjects:
|
||||||
@ -663,8 +663,30 @@ PrefabInstance:
|
|||||||
- targetCorrespondingSourceObject: {fileID: 8967231042952671610, guid: 4f2bf029cb06b084ba41defc8fc76731, type: 3}
|
- targetCorrespondingSourceObject: {fileID: 8967231042952671610, guid: 4f2bf029cb06b084ba41defc8fc76731, type: 3}
|
||||||
insertIndex: -1
|
insertIndex: -1
|
||||||
addedObject: {fileID: 8229589654595845064}
|
addedObject: {fileID: 8229589654595845064}
|
||||||
m_AddedComponents: []
|
m_AddedComponents:
|
||||||
|
- targetCorrespondingSourceObject: {fileID: 6952779389930089995, guid: 4f2bf029cb06b084ba41defc8fc76731, type: 3}
|
||||||
|
insertIndex: -1
|
||||||
|
addedObject: {fileID: 3263769952751147662}
|
||||||
m_SourcePrefab: {fileID: 100100000, guid: 4f2bf029cb06b084ba41defc8fc76731, type: 3}
|
m_SourcePrefab: {fileID: 100100000, guid: 4f2bf029cb06b084ba41defc8fc76731, type: 3}
|
||||||
|
--- !u!1 &3080325846008693413 stripped
|
||||||
|
GameObject:
|
||||||
|
m_CorrespondingSourceObject: {fileID: 6952779389930089995, guid: 4f2bf029cb06b084ba41defc8fc76731, type: 3}
|
||||||
|
m_PrefabInstance: {fileID: 5387070474184109230}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
--- !u!114 &3263769952751147662
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 3080325846008693413}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 7521841876f5b054aa4a0b0081ff8425, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
<UiType>k__BackingField: 1
|
||||||
|
_enableBlockImage: 0
|
||||||
--- !u!224 &3940853162783645140 stripped
|
--- !u!224 &3940853162783645140 stripped
|
||||||
RectTransform:
|
RectTransform:
|
||||||
m_CorrespondingSourceObject: {fileID: 8967231042952671610, guid: 4f2bf029cb06b084ba41defc8fc76731, type: 3}
|
m_CorrespondingSourceObject: {fileID: 8967231042952671610, guid: 4f2bf029cb06b084ba41defc8fc76731, type: 3}
|
@ -811,7 +811,9 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 11500000, guid: 7b3eb65dc42aeb84eba2397a9603e94d, type: 3}
|
m_Script: {fileID: 11500000, guid: 7b3eb65dc42aeb84eba2397a9603e94d, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
|
<UiType>k__BackingField: 3
|
||||||
_enableBlockImage: 1
|
_enableBlockImage: 1
|
||||||
|
InputActionMaps: 3
|
||||||
_uiActionsInputBinding: {fileID: 11400000, guid: 99d3d87bd43df65488e757c43a308f36, type: 2}
|
_uiActionsInputBinding: {fileID: 11400000, guid: 99d3d87bd43df65488e757c43a308f36, type: 2}
|
||||||
_messageLabel: {fileID: 3495127426411772216}
|
_messageLabel: {fileID: 3495127426411772216}
|
||||||
_messageLabelLocalizeStringEvent: {fileID: 7334955628972040157}
|
_messageLabelLocalizeStringEvent: {fileID: 7334955628972040157}
|
||||||
|
@ -6338,6 +6338,7 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 11500000, guid: 46c8396c996c804449b383960b44e812, type: 3}
|
m_Script: {fileID: 11500000, guid: 46c8396c996c804449b383960b44e812, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
|
<UiType>k__BackingField: 3
|
||||||
_enableBlockImage: 0
|
_enableBlockImage: 0
|
||||||
InputActionMaps: 3
|
InputActionMaps: 3
|
||||||
_uiActionsInputBinding: {fileID: 11400000, guid: 8073fcaf56fc7c34e996d0d47044f146, type: 2}
|
_uiActionsInputBinding: {fileID: 11400000, guid: 8073fcaf56fc7c34e996d0d47044f146, type: 2}
|
||||||
@ -6362,6 +6363,7 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 11500000, guid: 80dee5e1862248aab26236036049e5fc, type: 3}
|
m_Script: {fileID: 11500000, guid: 80dee5e1862248aab26236036049e5fc, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
|
_holdCompleteTime: 0
|
||||||
--- !u!1001 &4530765275021007961
|
--- !u!1001 &4530765275021007961
|
||||||
PrefabInstance:
|
PrefabInstance:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
BIN
Assets/_DDD/_Addressables/So/GameData/GameData.asset
(Stored with Git LFS)
BIN
Assets/_DDD/_Addressables/So/GameData/GameData.asset
(Stored with Git LFS)
Binary file not shown.
BIN
Assets/_DDD/_Addressables/So/GameData/UiData.asset
(Stored with Git LFS)
Normal file
BIN
Assets/_DDD/_Addressables/So/GameData/UiData.asset
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: dd182535820ec034b9d5a0315f93fa26
|
guid: d6d7638e05d740944a77a01f60b331c4
|
||||||
NativeFormatImporter:
|
NativeFormatImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
mainObjectFileID: 11400000
|
mainObjectFileID: 11400000
|
BIN
Assets/_DDD/_Addressables/So/PopupUiState.asset
(Stored with Git LFS)
BIN
Assets/_DDD/_Addressables/So/PopupUiState.asset
(Stored with Git LFS)
Binary file not shown.
@ -10,7 +10,7 @@ GameObject:
|
|||||||
m_Component:
|
m_Component:
|
||||||
- component: {fileID: 4347279445921954555}
|
- component: {fileID: 4347279445921954555}
|
||||||
m_Layer: 5
|
m_Layer: 5
|
||||||
m_Name: PopupUis
|
m_Name: PopupUiRoot
|
||||||
m_TagString: Untagged
|
m_TagString: Untagged
|
||||||
m_Icon: {fileID: 0}
|
m_Icon: {fileID: 0}
|
||||||
m_NavMeshLayer: 0
|
m_NavMeshLayer: 0
|
||||||
@ -38,6 +38,115 @@ RectTransform:
|
|||||||
m_AnchoredPosition: {x: 0, y: 0}
|
m_AnchoredPosition: {x: 0, y: 0}
|
||||||
m_SizeDelta: {x: 0, y: 0}
|
m_SizeDelta: {x: 0, y: 0}
|
||||||
m_Pivot: {x: 0.5, y: 0.5}
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!1 &1111901944139047714
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 6076800063500988294}
|
||||||
|
m_Layer: 5
|
||||||
|
m_Name: HudRoot
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &6076800063500988294
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1111901944139047714}
|
||||||
|
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: 1
|
||||||
|
m_Children:
|
||||||
|
- {fileID: 7916164406893547064}
|
||||||
|
m_Father: {fileID: 5760169274063006291}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0, y: 0}
|
||||||
|
m_AnchorMax: {x: 1, y: 1}
|
||||||
|
m_AnchoredPosition: {x: 0, y: 0}
|
||||||
|
m_SizeDelta: {x: 0, y: 0}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!1 &4130064528218324885
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 6174235207617529232}
|
||||||
|
m_Layer: 5
|
||||||
|
m_Name: CommonUiRoot
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &6174235207617529232
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4130064528218324885}
|
||||||
|
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: 1
|
||||||
|
m_Children:
|
||||||
|
- {fileID: 4191602006120035298}
|
||||||
|
- {fileID: 4862733150375458244}
|
||||||
|
m_Father: {fileID: 5760169274063006291}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0, y: 0}
|
||||||
|
m_AnchorMax: {x: 1, y: 1}
|
||||||
|
m_AnchoredPosition: {x: 0, y: 0}
|
||||||
|
m_SizeDelta: {x: 0, y: 0}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!1 &4851448928365776117
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 3090446084811068791}
|
||||||
|
m_Layer: 5
|
||||||
|
m_Name: InteractionUiRoot
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &3090446084811068791
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4851448928365776117}
|
||||||
|
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: 1
|
||||||
|
m_Children:
|
||||||
|
- {fileID: 496411955364970508}
|
||||||
|
m_Father: {fileID: 5760169274063006291}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0, y: 0}
|
||||||
|
m_AnchorMax: {x: 1, y: 1}
|
||||||
|
m_AnchoredPosition: {x: 0, y: 0}
|
||||||
|
m_SizeDelta: {x: 0, y: 0}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
--- !u!1 &6838253471355869082
|
--- !u!1 &6838253471355869082
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@ -73,11 +182,10 @@ RectTransform:
|
|||||||
m_LocalScale: {x: 0, y: 0, z: 0}
|
m_LocalScale: {x: 0, y: 0, z: 0}
|
||||||
m_ConstrainProportionsScale: 1
|
m_ConstrainProportionsScale: 1
|
||||||
m_Children:
|
m_Children:
|
||||||
- {fileID: 7916164406893547064}
|
- {fileID: 6076800063500988294}
|
||||||
- {fileID: 496411955364970508}
|
- {fileID: 3090446084811068791}
|
||||||
- {fileID: 4347279445921954555}
|
- {fileID: 4347279445921954555}
|
||||||
- {fileID: 4191602006120035298}
|
- {fileID: 6174235207617529232}
|
||||||
- {fileID: 4862733150375458244}
|
|
||||||
m_Father: {fileID: 0}
|
m_Father: {fileID: 0}
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
m_AnchorMin: {x: 0, y: 0}
|
m_AnchorMin: {x: 0, y: 0}
|
||||||
@ -219,13 +327,10 @@ MonoBehaviour:
|
|||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
_persistent: 1
|
_persistent: 1
|
||||||
_popupUiState:
|
_hudRoot: {fileID: 6076800063500988294}
|
||||||
m_AssetGUID: dd182535820ec034b9d5a0315f93fa26
|
_interactionUiRoot: {fileID: 3090446084811068791}
|
||||||
m_SubObjectName:
|
|
||||||
m_SubObjectType:
|
|
||||||
m_SubObjectGUID:
|
|
||||||
m_EditorAssetChanged: 1
|
|
||||||
_popupUiRoot: {fileID: 4347279445921954555}
|
_popupUiRoot: {fileID: 4347279445921954555}
|
||||||
|
_commonUiRoot: {fileID: 6174235207617529232}
|
||||||
--- !u!1001 &291049386471777514
|
--- !u!1001 &291049386471777514
|
||||||
PrefabInstance:
|
PrefabInstance:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@ -274,7 +379,7 @@ PrefabInstance:
|
|||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_Modification:
|
m_Modification:
|
||||||
serializedVersion: 3
|
serializedVersion: 3
|
||||||
m_TransformParent: {fileID: 5760169274063006291}
|
m_TransformParent: {fileID: 6076800063500988294}
|
||||||
m_Modifications:
|
m_Modifications:
|
||||||
- target: {fileID: 1353387648420519096, guid: 86a58b93c36851e4787861c23023b094, type: 3}
|
- target: {fileID: 1353387648420519096, guid: 86a58b93c36851e4787861c23023b094, type: 3}
|
||||||
propertyPath: m_AnchorMax.y
|
propertyPath: m_AnchorMax.y
|
||||||
@ -302,7 +407,7 @@ PrefabInstance:
|
|||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 3080325846008693413, guid: 86a58b93c36851e4787861c23023b094, type: 3}
|
- target: {fileID: 3080325846008693413, guid: 86a58b93c36851e4787861c23023b094, type: 3}
|
||||||
propertyPath: m_Name
|
propertyPath: m_Name
|
||||||
value: Hud
|
value: RestaurantHud
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 4664972416674662382, guid: 86a58b93c36851e4787861c23023b094, type: 3}
|
- target: {fileID: 4664972416674662382, guid: 86a58b93c36851e4787861c23023b094, type: 3}
|
||||||
propertyPath: m_Pivot.x
|
propertyPath: m_Pivot.x
|
||||||
@ -354,15 +459,15 @@ PrefabInstance:
|
|||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 4664972416674662382, guid: 86a58b93c36851e4787861c23023b094, type: 3}
|
- target: {fileID: 4664972416674662382, guid: 86a58b93c36851e4787861c23023b094, type: 3}
|
||||||
propertyPath: m_LocalRotation.x
|
propertyPath: m_LocalRotation.x
|
||||||
value: 0
|
value: -0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 4664972416674662382, guid: 86a58b93c36851e4787861c23023b094, type: 3}
|
- target: {fileID: 4664972416674662382, guid: 86a58b93c36851e4787861c23023b094, type: 3}
|
||||||
propertyPath: m_LocalRotation.y
|
propertyPath: m_LocalRotation.y
|
||||||
value: 0
|
value: -0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 4664972416674662382, guid: 86a58b93c36851e4787861c23023b094, type: 3}
|
- target: {fileID: 4664972416674662382, guid: 86a58b93c36851e4787861c23023b094, type: 3}
|
||||||
propertyPath: m_LocalRotation.z
|
propertyPath: m_LocalRotation.z
|
||||||
value: 0
|
value: -0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 4664972416674662382, guid: 86a58b93c36851e4787861c23023b094, type: 3}
|
- target: {fileID: 4664972416674662382, guid: 86a58b93c36851e4787861c23023b094, type: 3}
|
||||||
propertyPath: m_AnchoredPosition.x
|
propertyPath: m_AnchoredPosition.x
|
||||||
@ -1811,7 +1916,7 @@ PrefabInstance:
|
|||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_Modification:
|
m_Modification:
|
||||||
serializedVersion: 3
|
serializedVersion: 3
|
||||||
m_TransformParent: {fileID: 5760169274063006291}
|
m_TransformParent: {fileID: 6174235207617529232}
|
||||||
m_Modifications:
|
m_Modifications:
|
||||||
- target: {fileID: 1926278333613504521, guid: f84d9014b084dbf46b1c4d44fe5b63c3, type: 3}
|
- target: {fileID: 1926278333613504521, guid: f84d9014b084dbf46b1c4d44fe5b63c3, type: 3}
|
||||||
propertyPath: m_Name
|
propertyPath: m_Name
|
||||||
@ -1867,15 +1972,15 @@ PrefabInstance:
|
|||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 8122602890985372994, guid: f84d9014b084dbf46b1c4d44fe5b63c3, type: 3}
|
- target: {fileID: 8122602890985372994, guid: f84d9014b084dbf46b1c4d44fe5b63c3, type: 3}
|
||||||
propertyPath: m_LocalRotation.x
|
propertyPath: m_LocalRotation.x
|
||||||
value: 0
|
value: -0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 8122602890985372994, guid: f84d9014b084dbf46b1c4d44fe5b63c3, type: 3}
|
- target: {fileID: 8122602890985372994, guid: f84d9014b084dbf46b1c4d44fe5b63c3, type: 3}
|
||||||
propertyPath: m_LocalRotation.y
|
propertyPath: m_LocalRotation.y
|
||||||
value: 0
|
value: -0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 8122602890985372994, guid: f84d9014b084dbf46b1c4d44fe5b63c3, type: 3}
|
- target: {fileID: 8122602890985372994, guid: f84d9014b084dbf46b1c4d44fe5b63c3, type: 3}
|
||||||
propertyPath: m_LocalRotation.z
|
propertyPath: m_LocalRotation.z
|
||||||
value: 0
|
value: -0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 8122602890985372994, guid: f84d9014b084dbf46b1c4d44fe5b63c3, type: 3}
|
- target: {fileID: 8122602890985372994, guid: f84d9014b084dbf46b1c4d44fe5b63c3, type: 3}
|
||||||
propertyPath: m_AnchoredPosition.x
|
propertyPath: m_AnchoredPosition.x
|
||||||
@ -2079,7 +2184,7 @@ PrefabInstance:
|
|||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_Modification:
|
m_Modification:
|
||||||
serializedVersion: 3
|
serializedVersion: 3
|
||||||
m_TransformParent: {fileID: 5760169274063006291}
|
m_TransformParent: {fileID: 6174235207617529232}
|
||||||
m_Modifications:
|
m_Modifications:
|
||||||
- target: {fileID: 2726783183655360567, guid: 085fe4e2983c9ed4780abfb56bf5c322, type: 3}
|
- target: {fileID: 2726783183655360567, guid: 085fe4e2983c9ed4780abfb56bf5c322, type: 3}
|
||||||
propertyPath: m_Pivot.x
|
propertyPath: m_Pivot.x
|
||||||
@ -2131,15 +2236,15 @@ PrefabInstance:
|
|||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 2726783183655360567, guid: 085fe4e2983c9ed4780abfb56bf5c322, type: 3}
|
- target: {fileID: 2726783183655360567, guid: 085fe4e2983c9ed4780abfb56bf5c322, type: 3}
|
||||||
propertyPath: m_LocalRotation.x
|
propertyPath: m_LocalRotation.x
|
||||||
value: 0
|
value: -0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 2726783183655360567, guid: 085fe4e2983c9ed4780abfb56bf5c322, type: 3}
|
- target: {fileID: 2726783183655360567, guid: 085fe4e2983c9ed4780abfb56bf5c322, type: 3}
|
||||||
propertyPath: m_LocalRotation.y
|
propertyPath: m_LocalRotation.y
|
||||||
value: 0
|
value: -0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 2726783183655360567, guid: 085fe4e2983c9ed4780abfb56bf5c322, type: 3}
|
- target: {fileID: 2726783183655360567, guid: 085fe4e2983c9ed4780abfb56bf5c322, type: 3}
|
||||||
propertyPath: m_LocalRotation.z
|
propertyPath: m_LocalRotation.z
|
||||||
value: 0
|
value: -0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 2726783183655360567, guid: 085fe4e2983c9ed4780abfb56bf5c322, type: 3}
|
- target: {fileID: 2726783183655360567, guid: 085fe4e2983c9ed4780abfb56bf5c322, type: 3}
|
||||||
propertyPath: m_AnchoredPosition.x
|
propertyPath: m_AnchoredPosition.x
|
||||||
@ -2181,7 +2286,7 @@ PrefabInstance:
|
|||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_Modification:
|
m_Modification:
|
||||||
serializedVersion: 3
|
serializedVersion: 3
|
||||||
m_TransformParent: {fileID: 5760169274063006291}
|
m_TransformParent: {fileID: 3090446084811068791}
|
||||||
m_Modifications:
|
m_Modifications:
|
||||||
- target: {fileID: 507999590019405259, guid: 67b28d928cd16794eba49dade35d395d, type: 3}
|
- target: {fileID: 507999590019405259, guid: 67b28d928cd16794eba49dade35d395d, type: 3}
|
||||||
propertyPath: m_Name
|
propertyPath: m_Name
|
||||||
@ -2313,15 +2418,15 @@ PrefabInstance:
|
|||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 7858233056384553088, guid: 67b28d928cd16794eba49dade35d395d, type: 3}
|
- target: {fileID: 7858233056384553088, guid: 67b28d928cd16794eba49dade35d395d, type: 3}
|
||||||
propertyPath: m_LocalRotation.x
|
propertyPath: m_LocalRotation.x
|
||||||
value: 0
|
value: -0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 7858233056384553088, guid: 67b28d928cd16794eba49dade35d395d, type: 3}
|
- target: {fileID: 7858233056384553088, guid: 67b28d928cd16794eba49dade35d395d, type: 3}
|
||||||
propertyPath: m_LocalRotation.y
|
propertyPath: m_LocalRotation.y
|
||||||
value: 0
|
value: -0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 7858233056384553088, guid: 67b28d928cd16794eba49dade35d395d, type: 3}
|
- target: {fileID: 7858233056384553088, guid: 67b28d928cd16794eba49dade35d395d, type: 3}
|
||||||
propertyPath: m_LocalRotation.z
|
propertyPath: m_LocalRotation.z
|
||||||
value: 0
|
value: -0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 7858233056384553088, guid: 67b28d928cd16794eba49dade35d395d, type: 3}
|
- target: {fileID: 7858233056384553088, guid: 67b28d928cd16794eba49dade35d395d, type: 3}
|
||||||
propertyPath: m_AnchoredPosition.x
|
propertyPath: m_AnchoredPosition.x
|
||||||
|
BIN
Assets/_DDD/_ScriptAssets/So/ManagerDefinitionSo.asset
(Stored with Git LFS)
BIN
Assets/_DDD/_ScriptAssets/So/ManagerDefinitionSo.asset
(Stored with Git LFS)
Binary file not shown.
@ -8,8 +8,10 @@ namespace DDD
|
|||||||
public class GameData : ScriptSingleton<GameData>
|
public class GameData : ScriptSingleton<GameData>
|
||||||
{
|
{
|
||||||
[SerializeField] private AssetReference _gameLocalizationData;
|
[SerializeField] private AssetReference _gameLocalizationData;
|
||||||
|
[SerializeField] private AssetReference _uiData;
|
||||||
|
|
||||||
public GameLocalizationData LocalizationData { get; private set; }
|
public GameLocalizationData LocalizationData { get; private set; }
|
||||||
|
public UiData UiData { get; private set; }
|
||||||
|
|
||||||
private bool _isLoaded;
|
private bool _isLoaded;
|
||||||
|
|
||||||
@ -21,10 +23,16 @@ public async Task LoadData()
|
|||||||
}
|
}
|
||||||
|
|
||||||
var gameLocalizationDataHandle = _gameLocalizationData.LoadAssetAsync<GameLocalizationData>();
|
var gameLocalizationDataHandle = _gameLocalizationData.LoadAssetAsync<GameLocalizationData>();
|
||||||
|
var popupUiDataHandle = _uiData.LoadAssetAsync<UiData>();
|
||||||
|
|
||||||
await gameLocalizationDataHandle.Task;
|
await gameLocalizationDataHandle.Task;
|
||||||
|
await popupUiDataHandle.Task;
|
||||||
|
|
||||||
LocalizationData = gameLocalizationDataHandle.Result;
|
LocalizationData = gameLocalizationDataHandle.Result;
|
||||||
|
UiData = popupUiDataHandle.Result;
|
||||||
|
|
||||||
Debug.Assert(LocalizationData != null, "GameLocalizationData is null");
|
Debug.Assert(LocalizationData != null, "GameLocalizationData is null");
|
||||||
|
Debug.Assert(UiData != null, "UiData is null");
|
||||||
|
|
||||||
_isLoaded = true;
|
_isLoaded = true;
|
||||||
}
|
}
|
||||||
|
12
Assets/_DDD/_Scripts/GameData/PopupUiData.cs
Normal file
12
Assets/_DDD/_Scripts/GameData/PopupUiData.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Sirenix.OdinInspector;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace DDD
|
||||||
|
{
|
||||||
|
[CreateAssetMenu(fileName = "UiData", menuName = "GameData/UiData")]
|
||||||
|
public class UiData : SerializedScriptableObject
|
||||||
|
{
|
||||||
|
public Dictionary<GameFlowState, List<BaseUi>> FlowToUiMapping = new();
|
||||||
|
}
|
||||||
|
}
|
3
Assets/_DDD/_Scripts/GameData/PopupUiData.cs.meta
Normal file
3
Assets/_DDD/_Scripts/GameData/PopupUiData.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a0663996283946b0a51684c1047c24a1
|
||||||
|
timeCreated: 1755751458
|
@ -28,7 +28,7 @@ public void PreInit()
|
|||||||
|
|
||||||
public Task Init()
|
public Task Init()
|
||||||
{
|
{
|
||||||
return Task.CompletedTask; ;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void PostInit()
|
public async void PostInit()
|
||||||
|
@ -1,17 +1,14 @@
|
|||||||
using UnityEngine;
|
|
||||||
using UnityEngine.AddressableAssets;
|
|
||||||
|
|
||||||
namespace DDD
|
namespace DDD
|
||||||
{
|
{
|
||||||
public class GameState : ScriptSingleton<GameState>
|
public class GameState : ScriptSingleton<GameState>
|
||||||
{
|
{
|
||||||
[SerializeField] private AssetReference _gameLevelState;
|
|
||||||
|
|
||||||
public GameLevelState LevelState { get; private set; }
|
public GameLevelState LevelState { get; private set; }
|
||||||
|
public UiState UiState { get; private set; }
|
||||||
|
|
||||||
private void OnEnable()
|
private void OnEnable()
|
||||||
{
|
{
|
||||||
LevelState = CreateInstance<GameLevelState>();
|
LevelState = CreateInstance<GameLevelState>();
|
||||||
|
UiState = CreateInstance<UiState>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,14 +2,24 @@
|
|||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using TMPro;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using DDD.MVVM;
|
|
||||||
|
|
||||||
namespace DDD
|
namespace DDD
|
||||||
{
|
{
|
||||||
|
public enum UiType
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Hud,
|
||||||
|
Interaction,
|
||||||
|
Popup,
|
||||||
|
Common
|
||||||
|
}
|
||||||
|
|
||||||
public abstract class BaseUi : MonoBehaviour
|
public abstract class BaseUi : MonoBehaviour
|
||||||
{
|
{
|
||||||
|
[field: SerializeField] public UiType UiType { get; set; }
|
||||||
[SerializeField] protected bool _enableBlockImage;
|
[SerializeField] protected bool _enableBlockImage;
|
||||||
|
|
||||||
protected CanvasGroup _canvasGroup;
|
protected CanvasGroup _canvasGroup;
|
||||||
@ -27,7 +37,6 @@ protected virtual void Awake()
|
|||||||
_blockImage = transform.Find(CommonConstants.BlockImage)?.gameObject;
|
_blockImage = transform.Find(CommonConstants.BlockImage)?.gameObject;
|
||||||
|
|
||||||
_bindingContext = new BindingContext();
|
_bindingContext = new BindingContext();
|
||||||
SetupAutoBindings();
|
|
||||||
SetupBindings();
|
SetupBindings();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,7 +47,6 @@ protected virtual void OnEnable()
|
|||||||
|
|
||||||
protected virtual void Start()
|
protected virtual void Start()
|
||||||
{
|
{
|
||||||
TryRegister();
|
|
||||||
ClosePanel();
|
ClosePanel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,8 +66,20 @@ protected virtual void OnDestroy()
|
|||||||
_bindingContext?.Dispose();
|
_bindingContext?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void TryRegister() { }
|
public virtual void CreateInitialize()
|
||||||
protected virtual void TryUnregister() { }
|
{
|
||||||
|
TryRegister();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void TryRegister()
|
||||||
|
{
|
||||||
|
UiManager.Instance.UiState.RegisterUI(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void TryUnregister()
|
||||||
|
{
|
||||||
|
UiManager.Instance.UiState.UnregisterUI(this);
|
||||||
|
}
|
||||||
|
|
||||||
// BaseUi 메서드들을 직접 구현
|
// BaseUi 메서드들을 직접 구현
|
||||||
public virtual void OpenPanel()
|
public virtual void OpenPanel()
|
||||||
@ -93,74 +113,6 @@ public virtual void SetUiInteractable(bool active)
|
|||||||
|
|
||||||
public bool IsOpenPanel() => _panel && _panel.activeInHierarchy;
|
public bool IsOpenPanel() => _panel && _panel.activeInHierarchy;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Attribute 기반 자동 바인딩 설정
|
|
||||||
/// </summary>
|
|
||||||
private void SetupAutoBindings()
|
|
||||||
{
|
|
||||||
var fields = GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public)
|
|
||||||
.Where(f => f.GetCustomAttribute<BindToAttribute>() != null);
|
|
||||||
|
|
||||||
foreach (var field in fields)
|
|
||||||
{
|
|
||||||
var bindAttribute = field.GetCustomAttribute<BindToAttribute>();
|
|
||||||
SetupBinding(field, bindAttribute);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 컬렉션 바인딩 설정
|
|
||||||
var collectionFields = GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public)
|
|
||||||
.Where(f => f.GetCustomAttribute<BindCollectionAttribute>() != null);
|
|
||||||
|
|
||||||
foreach (var field in collectionFields)
|
|
||||||
{
|
|
||||||
var bindAttribute = field.GetCustomAttribute<BindCollectionAttribute>();
|
|
||||||
SetupCollectionBinding(field, bindAttribute);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 개별 필드의 바인딩 설정
|
|
||||||
/// </summary>
|
|
||||||
private void SetupBinding(FieldInfo field, BindToAttribute bindAttribute)
|
|
||||||
{
|
|
||||||
var target = field.GetValue(this);
|
|
||||||
|
|
||||||
IValueConverter converter = null;
|
|
||||||
if (bindAttribute.ConverterType != null)
|
|
||||||
{
|
|
||||||
converter = Activator.CreateInstance(bindAttribute.ConverterType) as IValueConverter;
|
|
||||||
}
|
|
||||||
|
|
||||||
// UI 컴포넌트 타입별 바인딩 타겟 생성
|
|
||||||
IBindingTarget bindingTarget = target switch
|
|
||||||
{
|
|
||||||
Text text => new TextBindingTarget(text, bindAttribute.PropertyPath),
|
|
||||||
Image image => new ImageBindingTarget(image, bindAttribute.PropertyPath),
|
|
||||||
GameObject go => new ActiveBindingTarget(go, bindAttribute.PropertyPath),
|
|
||||||
Slider slider => new SliderBindingTarget(slider, bindAttribute.PropertyPath),
|
|
||||||
_ => null
|
|
||||||
};
|
|
||||||
|
|
||||||
if (bindingTarget != null)
|
|
||||||
{
|
|
||||||
_bindingContext.Bind(bindAttribute.PropertyPath, bindingTarget, converter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 컬렉션 바인딩 설정
|
|
||||||
/// </summary>
|
|
||||||
private void SetupCollectionBinding(FieldInfo field, BindCollectionAttribute bindAttribute)
|
|
||||||
{
|
|
||||||
var target = field.GetValue(this);
|
|
||||||
|
|
||||||
if (target is Transform parent)
|
|
||||||
{
|
|
||||||
// 컬렉션 바인딩 로직 (필요시 확장)
|
|
||||||
Debug.Log($"Collection binding for {bindAttribute.PropertyPath} is set up on {parent.name}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 추가 바인딩 설정 - 하위 클래스에서 구현
|
/// 추가 바인딩 설정 - 하위 클래스에서 구현
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -181,30 +133,5 @@ protected virtual void HandleCustomPropertyChanged(string propertyName)
|
|||||||
{
|
{
|
||||||
// 하위 클래스에서 구현
|
// 하위 클래스에서 구현
|
||||||
}
|
}
|
||||||
|
|
||||||
// 수동 바인딩 헬퍼 메서드들
|
|
||||||
protected void BindText(Text text, string propertyPath, IValueConverter converter = null)
|
|
||||||
{
|
|
||||||
var target = new TextBindingTarget(text, propertyPath);
|
|
||||||
_bindingContext?.Bind(propertyPath, target, converter);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void BindImage(Image image, string propertyPath, IValueConverter converter = null)
|
|
||||||
{
|
|
||||||
var target = new ImageBindingTarget(image, propertyPath);
|
|
||||||
_bindingContext?.Bind(propertyPath, target, converter);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void BindActive(GameObject gameObject, string propertyPath, IValueConverter converter = null)
|
|
||||||
{
|
|
||||||
var target = new ActiveBindingTarget(gameObject, propertyPath);
|
|
||||||
_bindingContext?.Bind(propertyPath, target, converter);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void BindSlider(Slider slider, string propertyPath, IValueConverter converter = null)
|
|
||||||
{
|
|
||||||
var target = new SliderBindingTarget(slider, propertyPath);
|
|
||||||
_bindingContext?.Bind(propertyPath, target, converter);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,5 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using DG.Tweening;
|
using DG.Tweening;
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace DDD
|
namespace DDD
|
||||||
{
|
{
|
||||||
@ -15,6 +14,8 @@ protected override void Awake()
|
|||||||
|
|
||||||
protected override void TryRegister()
|
protected override void TryRegister()
|
||||||
{
|
{
|
||||||
|
base.TryRegister();
|
||||||
|
|
||||||
EventBus.Register<FadeInEvent>(this);
|
EventBus.Register<FadeInEvent>(this);
|
||||||
EventBus.Register<FadeOutEvent>(this);
|
EventBus.Register<FadeOutEvent>(this);
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ protected override void Awake()
|
|||||||
_canvasGroup.alpha = 0;
|
_canvasGroup.alpha = 0;
|
||||||
_messageText.text = null;
|
_messageText.text = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void TryRegister()
|
protected override void TryRegister()
|
||||||
{
|
{
|
||||||
base.TryRegister();
|
base.TryRegister();
|
||||||
|
@ -24,7 +24,7 @@ protected override void Awake()
|
|||||||
|
|
||||||
_filledImage.fillAmount = 0f;
|
_filledImage.fillAmount = 0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void TryRegister()
|
protected override void TryRegister()
|
||||||
{
|
{
|
||||||
base.TryRegister();
|
base.TryRegister();
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace DDD.MVVM
|
namespace DDD
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 불린 값을 반전시키는 컨버터
|
/// 불린 값을 반전시키는 컨버터
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
namespace DDD.MVVM
|
namespace DDD
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 값 변환기 인터페이스
|
/// 값 변환기 인터페이스
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using DDD.MVVM;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace DDD
|
namespace DDD
|
||||||
@ -11,41 +10,31 @@ namespace DDD
|
|||||||
public class RestaurantManagementViewModel : SimpleViewModel, IEventHandler<TodayMenuRemovedEvent>
|
public class RestaurantManagementViewModel : SimpleViewModel, IEventHandler<TodayMenuRemovedEvent>
|
||||||
{
|
{
|
||||||
// 홀드 진행 상태 관리
|
// 홀드 진행 상태 관리
|
||||||
|
[SerializeField] private float _holdCompleteTime = 1f;
|
||||||
private bool _isHolding;
|
private bool _isHolding;
|
||||||
private float _elapsedTime;
|
|
||||||
private float _holdCompleteTime = 1f;
|
private float _holdProgress;
|
||||||
|
public float HoldProgress
|
||||||
|
{
|
||||||
|
get => _holdProgress;
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
if (SetField(ref _holdProgress, value))
|
||||||
|
{
|
||||||
|
OnPropertyChanged(nameof(NormalizedHoldProgress));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 홀드 진행률을 0~1 범위로 변환한 값
|
||||||
|
/// </summary>
|
||||||
|
public float NormalizedHoldProgress => _holdCompleteTime <= 0f ? 0f : Mathf.Clamp01(_holdProgress / _holdCompleteTime);
|
||||||
|
|
||||||
// 탭 상태 관리
|
// 탭 상태 관리
|
||||||
private SectionButtonType _currentSection = SectionButtonType.Menu;
|
private SectionButtonType _currentSection = SectionButtonType.Menu;
|
||||||
private InventoryCategoryType _currentCategory = InventoryCategoryType.Food;
|
private InventoryCategoryType _currentCategory = InventoryCategoryType.Food;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 현재 홀드 상태
|
|
||||||
/// </summary>
|
|
||||||
public bool IsHolding
|
|
||||||
{
|
|
||||||
get => _isHolding;
|
|
||||||
private set => SetField(ref _isHolding, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 홀드 진행 시간 (0.0 ~ 1.0)
|
|
||||||
/// </summary>
|
|
||||||
public float HoldProgress
|
|
||||||
{
|
|
||||||
get => _elapsedTime;
|
|
||||||
private set => SetField(ref _elapsedTime, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 홀드 완료에 필요한 시간
|
|
||||||
/// </summary>
|
|
||||||
public float HoldCompleteTime
|
|
||||||
{
|
|
||||||
get => _holdCompleteTime;
|
|
||||||
set => SetField(ref _holdCompleteTime, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 현재 선택된 섹션
|
/// 현재 선택된 섹션
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -67,13 +56,7 @@ public InventoryCategoryType CurrentCategory
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 배치 완료 가능 여부 (체크리스트 완료 상태)
|
/// 배치 완료 가능 여부 (체크리스트 완료 상태)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool CanCompleteBatch =>
|
public bool CanCompleteBatch => RestaurantState.Instance.ManagementState.GetChecklistStates().All(state => state);
|
||||||
RestaurantState.Instance.ManagementState.GetChecklistStates().All(state => state);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 홀드 진행률을 0~1 범위로 변환한 값
|
|
||||||
/// </summary>
|
|
||||||
public float NormalizedHoldProgress => HoldCompleteTime <= 0f ? 1f : Mathf.Clamp01(HoldProgress / HoldCompleteTime);
|
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@ -103,9 +86,9 @@ private void UnregisterEvents()
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void UpdateHoldProgress()
|
public void UpdateHoldProgress()
|
||||||
{
|
{
|
||||||
if (!IsHolding) return;
|
if (_isHolding == false) return;
|
||||||
|
|
||||||
if (HoldCompleteTime <= 0f)
|
if (_holdCompleteTime <= 0f)
|
||||||
{
|
{
|
||||||
ProcessCompleteBatch();
|
ProcessCompleteBatch();
|
||||||
return;
|
return;
|
||||||
@ -114,13 +97,10 @@ public void UpdateHoldProgress()
|
|||||||
var deltaTime = Time.deltaTime;
|
var deltaTime = Time.deltaTime;
|
||||||
HoldProgress += deltaTime;
|
HoldProgress += deltaTime;
|
||||||
|
|
||||||
if (HoldProgress >= HoldCompleteTime)
|
if (HoldProgress >= _holdCompleteTime)
|
||||||
{
|
{
|
||||||
ProcessCompleteBatch();
|
ProcessCompleteBatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
// UI 업데이트를 위한 정규화된 진행률 알림
|
|
||||||
OnPropertyChanged(nameof(NormalizedHoldProgress));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -128,9 +108,8 @@ public void UpdateHoldProgress()
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void StartHold()
|
public void StartHold()
|
||||||
{
|
{
|
||||||
IsHolding = true;
|
_isHolding = true;
|
||||||
HoldProgress = 0f;
|
HoldProgress = 0f;
|
||||||
OnPropertyChanged(nameof(NormalizedHoldProgress));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -143,9 +122,8 @@ public void CancelHold()
|
|||||||
|
|
||||||
private void ResetHoldState()
|
private void ResetHoldState()
|
||||||
{
|
{
|
||||||
IsHolding = false;
|
_isHolding = false;
|
||||||
HoldProgress = 0f;
|
HoldProgress = 0f;
|
||||||
OnPropertyChanged(nameof(NormalizedHoldProgress));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
namespace DDD.MVVM
|
namespace DDD
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 서비스 계층의 기본 인터페이스
|
/// 서비스 계층의 기본 인터페이스
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace DDD.MVVM
|
namespace DDD
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 인벤토리 관련 비즈니스 로직을 담당하는 서비스
|
/// 인벤토리 관련 비즈니스 로직을 담당하는 서비스
|
||||||
|
@ -1,114 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace DDD.MVVM
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// UI 요소를 ViewModel 속성에 바인딩하기 위한 Attribute
|
|
||||||
/// Inspector에서 바인딩 정보를 시각적으로 확인할 수 있도록 지원
|
|
||||||
/// </summary>
|
|
||||||
[System.AttributeUsage(System.AttributeTargets.Field)]
|
|
||||||
public class BindToAttribute : System.Attribute
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 바인딩할 ViewModel 속성의 경로 (nameof 사용 권장)
|
|
||||||
/// </summary>
|
|
||||||
public string PropertyPath { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 값 변환기 타입 (선택사항)
|
|
||||||
/// </summary>
|
|
||||||
public System.Type ConverterType { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 바인딩 Attribute 생성자
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="propertyPath">바인딩할 속성 경로 (nameof 사용 권장)</param>
|
|
||||||
/// <param name="converterType">값 변환기 타입 (선택사항)</param>
|
|
||||||
public BindToAttribute(string propertyPath, System.Type converterType = null)
|
|
||||||
{
|
|
||||||
PropertyPath = propertyPath;
|
|
||||||
ConverterType = converterType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// /// <summary>
|
|
||||||
// /// 타입 안전한 바인딩 Attribute (제네릭 버전)
|
|
||||||
// /// 특정 ViewModel 타입에 대한 바인딩을 명시적으로 지정
|
|
||||||
// /// </summary>
|
|
||||||
// /// <typeparam name="TViewModel">바인딩할 ViewModel 타입</typeparam>
|
|
||||||
// [System.AttributeUsage(System.AttributeTargets.Field)]
|
|
||||||
// public class BindToAttribute<TViewModel> : System.Attribute where TViewModel : class
|
|
||||||
// {
|
|
||||||
// /// <summary>
|
|
||||||
// /// 바인딩할 ViewModel 속성의 경로
|
|
||||||
// /// </summary>
|
|
||||||
// public string PropertyPath { get; }
|
|
||||||
//
|
|
||||||
// /// <summary>
|
|
||||||
// /// 값 변환기 타입 (선택사항)
|
|
||||||
// /// </summary>
|
|
||||||
// public System.Type ConverterType { get; }
|
|
||||||
//
|
|
||||||
// /// <summary>
|
|
||||||
// /// 타입 안전한 바인딩 Attribute 생성자
|
|
||||||
// /// </summary>
|
|
||||||
// /// <param name="propertyPath">바인딩할 속성 경로</param>
|
|
||||||
// /// <param name="converterType">값 변환기 타입 (선택사항)</param>
|
|
||||||
// public BindToAttribute(string propertyPath, System.Type converterType = null)
|
|
||||||
// {
|
|
||||||
// PropertyPath = propertyPath;
|
|
||||||
// ConverterType = converterType;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 컬렉션 바인딩을 위한 Attribute
|
|
||||||
/// 동적으로 생성되는 UI 요소들을 컬렉션에 바인딩
|
|
||||||
/// </summary>
|
|
||||||
[System.AttributeUsage(System.AttributeTargets.Field)]
|
|
||||||
public class BindCollectionAttribute : System.Attribute
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 바인딩할 컬렉션 속성의 경로
|
|
||||||
/// </summary>
|
|
||||||
public string PropertyPath { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 아이템 프리팹의 필드명 또는 속성명
|
|
||||||
/// </summary>
|
|
||||||
public string ItemPrefabReference { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 컬렉션 바인딩 Attribute 생성자
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="propertyPath">바인딩할 컬렉션 속성 경로</param>
|
|
||||||
/// <param name="itemPrefabReference">아이템 프리팹 참조</param>
|
|
||||||
public BindCollectionAttribute(string propertyPath, string itemPrefabReference = null)
|
|
||||||
{
|
|
||||||
PropertyPath = propertyPath;
|
|
||||||
ItemPrefabReference = itemPrefabReference;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 커맨드 바인딩을 위한 Attribute
|
|
||||||
/// 버튼 클릭 등의 이벤트를 ViewModel 메서드에 바인딩
|
|
||||||
/// </summary>
|
|
||||||
[System.AttributeUsage(System.AttributeTargets.Field)]
|
|
||||||
public class BindCommandAttribute : System.Attribute
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 바인딩할 ViewModel 메서드 이름
|
|
||||||
/// </summary>
|
|
||||||
public string MethodName { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 커맨드 바인딩 Attribute 생성자
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="methodName">바인딩할 메서드 이름</param>
|
|
||||||
public BindCommandAttribute(string methodName)
|
|
||||||
{
|
|
||||||
MethodName = methodName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 279b3238907a3564f842594af646eab7
|
|
@ -2,113 +2,12 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using TMPro;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
|
|
||||||
namespace DDD.MVVM
|
namespace DDD
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// 바인딩 타겟 인터페이스
|
|
||||||
/// UI 요소와 ViewModel 속성을 연결하는 역할
|
|
||||||
/// </summary>
|
|
||||||
public interface IBindingTarget
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 바인딩된 속성의 경로
|
|
||||||
/// </summary>
|
|
||||||
string PropertyPath { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// UI 요소의 값을 업데이트
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">새로운 값</param>
|
|
||||||
void UpdateValue(object value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Text 컴포넌트에 대한 바인딩 타겟
|
|
||||||
/// </summary>
|
|
||||||
public class TextBindingTarget : IBindingTarget
|
|
||||||
{
|
|
||||||
private readonly Text _text;
|
|
||||||
public string PropertyPath { get; }
|
|
||||||
|
|
||||||
public TextBindingTarget(Text text, string propertyPath)
|
|
||||||
{
|
|
||||||
_text = text;
|
|
||||||
PropertyPath = propertyPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateValue(object value)
|
|
||||||
{
|
|
||||||
if (_text != null)
|
|
||||||
_text.text = value?.ToString() ?? string.Empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Image 컴포넌트에 대한 바인딩 타겟
|
|
||||||
/// </summary>
|
|
||||||
public class ImageBindingTarget : IBindingTarget
|
|
||||||
{
|
|
||||||
private readonly Image _image;
|
|
||||||
public string PropertyPath { get; }
|
|
||||||
|
|
||||||
public ImageBindingTarget(Image image, string propertyPath)
|
|
||||||
{
|
|
||||||
_image = image;
|
|
||||||
PropertyPath = propertyPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateValue(object value)
|
|
||||||
{
|
|
||||||
if (_image != null && value is Sprite sprite)
|
|
||||||
_image.sprite = sprite;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// GameObject의 활성화 상태에 대한 바인딩 타겟
|
|
||||||
/// </summary>
|
|
||||||
public class ActiveBindingTarget : IBindingTarget
|
|
||||||
{
|
|
||||||
private readonly GameObject _gameObject;
|
|
||||||
public string PropertyPath { get; }
|
|
||||||
|
|
||||||
public ActiveBindingTarget(GameObject gameObject, string propertyPath)
|
|
||||||
{
|
|
||||||
_gameObject = gameObject;
|
|
||||||
PropertyPath = propertyPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateValue(object value)
|
|
||||||
{
|
|
||||||
if (_gameObject != null)
|
|
||||||
_gameObject.SetActive(value is bool active && active);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Slider 컴포넌트에 대한 바인딩 타겟
|
|
||||||
/// </summary>
|
|
||||||
public class SliderBindingTarget : IBindingTarget
|
|
||||||
{
|
|
||||||
private readonly Slider _slider;
|
|
||||||
public string PropertyPath { get; }
|
|
||||||
|
|
||||||
public SliderBindingTarget(Slider slider, string propertyPath)
|
|
||||||
{
|
|
||||||
_slider = slider;
|
|
||||||
PropertyPath = propertyPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateValue(object value)
|
|
||||||
{
|
|
||||||
if (_slider != null && value is float floatValue)
|
|
||||||
_slider.value = floatValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 바인딩 컨텍스트 - ViewModel과 View 간의 데이터 바인딩을 관리
|
/// 바인딩 컨텍스트 - ViewModel과 View 간의 데이터 바인딩을 관리
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
39
Assets/_DDD/_Scripts/GameUi/New/Utils/BindingHelper.cs
Normal file
39
Assets/_DDD/_Scripts/GameUi/New/Utils/BindingHelper.cs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
using TMPro;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace DDD
|
||||||
|
{
|
||||||
|
public static class BindingHelper
|
||||||
|
{
|
||||||
|
public static void BindText(BindingContext context, TextMeshProUGUI text, string propertyPath, IValueConverter converter = null)
|
||||||
|
{
|
||||||
|
var target = new TextBindingTarget(text, propertyPath);
|
||||||
|
context?.Bind(propertyPath, target, converter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void BindImage(BindingContext context, Image image, string propertyPath, IValueConverter converter = null)
|
||||||
|
{
|
||||||
|
var target = new ImageBindingTarget(image, propertyPath);
|
||||||
|
context?.Bind(propertyPath, target, converter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void BindImageFilled(BindingContext context, Image image, string propertyPath, IValueConverter converter = null)
|
||||||
|
{
|
||||||
|
var target = new ImageFilledBindingTarget(image, propertyPath);
|
||||||
|
context?.Bind(propertyPath, target, converter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void BindActive(BindingContext context, GameObject gameObject, string propertyPath, IValueConverter converter = null)
|
||||||
|
{
|
||||||
|
var target = new ActiveBindingTarget(gameObject, propertyPath);
|
||||||
|
context?.Bind(propertyPath, target, converter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void BindSlider(BindingContext context, Slider slider, string propertyPath, IValueConverter converter = null)
|
||||||
|
{
|
||||||
|
var target = new SliderBindingTarget(slider, propertyPath);
|
||||||
|
context?.Bind(propertyPath, target, converter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a76b583779de40c0b4b3a922c4efb82d
|
||||||
|
timeCreated: 1755747839
|
118
Assets/_DDD/_Scripts/GameUi/New/Utils/IBindingTarget.cs
Normal file
118
Assets/_DDD/_Scripts/GameUi/New/Utils/IBindingTarget.cs
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
using TMPro;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace DDD
|
||||||
|
{
|
||||||
|
public interface IBindingTarget
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 바인딩된 속성의 경로
|
||||||
|
/// </summary>
|
||||||
|
string PropertyPath { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// UI 요소의 값을 업데이트
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">새로운 값</param>
|
||||||
|
void UpdateValue(object value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TextBindingTarget : IBindingTarget
|
||||||
|
{
|
||||||
|
private readonly TextMeshProUGUI _text;
|
||||||
|
public string PropertyPath { get; }
|
||||||
|
|
||||||
|
public TextBindingTarget(TextMeshProUGUI text, string propertyPath)
|
||||||
|
{
|
||||||
|
_text = text;
|
||||||
|
PropertyPath = propertyPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateValue(object value)
|
||||||
|
{
|
||||||
|
if (_text != null)
|
||||||
|
{
|
||||||
|
_text.text = value?.ToString() ?? string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ImageBindingTarget : IBindingTarget
|
||||||
|
{
|
||||||
|
private readonly Image _image;
|
||||||
|
public string PropertyPath { get; }
|
||||||
|
|
||||||
|
public ImageBindingTarget(Image image, string propertyPath)
|
||||||
|
{
|
||||||
|
_image = image;
|
||||||
|
PropertyPath = propertyPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateValue(object value)
|
||||||
|
{
|
||||||
|
if (_image != null && value is Sprite sprite)
|
||||||
|
{
|
||||||
|
_image.sprite = sprite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ImageFilledBindingTarget : IBindingTarget
|
||||||
|
{
|
||||||
|
private readonly Image _image;
|
||||||
|
public string PropertyPath { get; }
|
||||||
|
|
||||||
|
public ImageFilledBindingTarget(Image image, string propertyPath)
|
||||||
|
{
|
||||||
|
_image = image;
|
||||||
|
PropertyPath = propertyPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateValue(object value)
|
||||||
|
{
|
||||||
|
if (_image != null && value is float floatValue)
|
||||||
|
{
|
||||||
|
_image.fillAmount = Mathf.Clamp01(floatValue); // 0-1 범위로 제한
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ActiveBindingTarget : IBindingTarget
|
||||||
|
{
|
||||||
|
private readonly GameObject _gameObject;
|
||||||
|
public string PropertyPath { get; }
|
||||||
|
|
||||||
|
public ActiveBindingTarget(GameObject go, string propertyPath)
|
||||||
|
{
|
||||||
|
_gameObject = go;
|
||||||
|
PropertyPath = propertyPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateValue(object value)
|
||||||
|
{
|
||||||
|
if (_gameObject != null)
|
||||||
|
{
|
||||||
|
_gameObject.SetActive(value is true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SliderBindingTarget : IBindingTarget
|
||||||
|
{
|
||||||
|
private readonly Slider _slider;
|
||||||
|
public string PropertyPath { get; }
|
||||||
|
|
||||||
|
public SliderBindingTarget(Slider slider, string propertyPath)
|
||||||
|
{
|
||||||
|
_slider = slider;
|
||||||
|
PropertyPath = propertyPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateValue(object value)
|
||||||
|
{
|
||||||
|
if (_slider != null && value is float floatValue)
|
||||||
|
_slider.value = floatValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: cd44087c256644b9815bfdc23ac4b29f
|
||||||
|
timeCreated: 1755749119
|
@ -1,24 +0,0 @@
|
|||||||
namespace DDD.MVVM
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 입력 처리 단계를 나타내는 열거형
|
|
||||||
/// 매직 스트링을 제거하고 타입 안전성을 제공
|
|
||||||
/// </summary>
|
|
||||||
public enum InputPhaseType
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 입력이 시작됨
|
|
||||||
/// </summary>
|
|
||||||
Started,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 입력이 수행됨
|
|
||||||
/// </summary>
|
|
||||||
Performed,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 입력이 취소됨
|
|
||||||
/// </summary>
|
|
||||||
Canceled
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 5c9b66b101f99e1458e01b9e0653935f
|
|
@ -10,8 +10,11 @@ public abstract class SimpleViewModel : MonoBehaviour, INotifyPropertyChanged
|
|||||||
public event PropertyChangedEventHandler PropertyChanged;
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
protected virtual void Awake() { }
|
protected virtual void Awake() { }
|
||||||
|
protected virtual void OnEnable() { }
|
||||||
protected virtual void Start() { }
|
protected virtual void Start() { }
|
||||||
|
protected virtual void OnDisable() { }
|
||||||
protected virtual void OnDestroy() { }
|
protected virtual void OnDestroy() { }
|
||||||
|
|
||||||
public virtual void Initialize() { }
|
public virtual void Initialize() { }
|
||||||
public virtual void Cleanup() { }
|
public virtual void Cleanup() { }
|
||||||
|
|
||||||
@ -35,6 +38,7 @@ protected virtual void OnPropertyChanged([CallerMemberName] string propertyName
|
|||||||
protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
|
protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
|
||||||
{
|
{
|
||||||
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
|
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
|
||||||
|
|
||||||
field = value;
|
field = value;
|
||||||
OnPropertyChanged(propertyName);
|
OnPropertyChanged(propertyName);
|
||||||
return true;
|
return true;
|
||||||
@ -64,24 +68,11 @@ protected void EndUpdate()
|
|||||||
if (_pendingNotifications.Count > 0)
|
if (_pendingNotifications.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (var prop in _pendingNotifications)
|
foreach (var prop in _pendingNotifications)
|
||||||
|
{
|
||||||
OnPropertyChanged(prop);
|
OnPropertyChanged(prop);
|
||||||
|
}
|
||||||
_pendingNotifications.Clear();
|
_pendingNotifications.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// PropertyChanged 이벤트 발생 (배치 업데이트 고려)
|
|
||||||
/// </summary>
|
|
||||||
protected virtual void OnPropertyChangedInternal([CallerMemberName] string propertyName = null)
|
|
||||||
{
|
|
||||||
if (_isUpdating)
|
|
||||||
{
|
|
||||||
_pendingNotifications.Add(propertyName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
OnPropertyChanged(propertyName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,9 +1,8 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace DDD.MVVM
|
namespace DDD
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 인벤토리 UI의 ViewModel
|
/// 인벤토리 UI의 ViewModel
|
||||||
@ -12,8 +11,7 @@ namespace DDD.MVVM
|
|||||||
public class InventoryViewModel : SimpleViewModel, IEventHandler<InventoryChangedEvent>,
|
public class InventoryViewModel : SimpleViewModel, IEventHandler<InventoryChangedEvent>,
|
||||||
IEventHandler<TodayMenuAddedEvent>, IEventHandler<TodayMenuRemovedEvent>
|
IEventHandler<TodayMenuAddedEvent>, IEventHandler<TodayMenuRemovedEvent>
|
||||||
{
|
{
|
||||||
[Header("Services")]
|
private InventoryService _inventoryService;
|
||||||
[SerializeField] private InventoryService _inventoryService;
|
|
||||||
|
|
||||||
// Private fields for properties
|
// Private fields for properties
|
||||||
private InventoryCategoryType _currentCategory = InventoryCategoryType.Food;
|
private InventoryCategoryType _currentCategory = InventoryCategoryType.Food;
|
||||||
@ -33,8 +31,6 @@ public InventoryCategoryType CurrentCategory
|
|||||||
if (SetField(ref _currentCategory, value))
|
if (SetField(ref _currentCategory, value))
|
||||||
{
|
{
|
||||||
UpdateVisibleItems();
|
UpdateVisibleItems();
|
||||||
// 연관된 계산된 속성들도 알림
|
|
||||||
OnPropertyChanged(nameof(CategoryDisplayText));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -81,21 +77,6 @@ public ItemViewModel SelectedItem
|
|||||||
set => SetField(ref _selectedItem, value);
|
set => SetField(ref _selectedItem, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Computed Properties (계산된 속성들)
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 카테고리 표시 텍스트 (한국어)
|
|
||||||
/// </summary>
|
|
||||||
public string CategoryDisplayText => CurrentCategory switch
|
|
||||||
{
|
|
||||||
InventoryCategoryType.Food => "음식",
|
|
||||||
InventoryCategoryType.Drink => "음료",
|
|
||||||
InventoryCategoryType.Ingredient => "재료",
|
|
||||||
InventoryCategoryType.Cookware => "조리도구",
|
|
||||||
InventoryCategoryType.Special => "특수",
|
|
||||||
_ => "전체"
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 보이는 아이템들 중 실제 보유한 아이템이 있는지 확인
|
/// 보이는 아이템들 중 실제 보유한 아이템이 있는지 확인
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 36adabeb3767cf64684116798ff0ef30
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 76b62bf64be94ab4bb1e4b610da29fa4
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
@ -1,210 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.UI;
|
|
||||||
|
|
||||||
namespace DDD.MVVM
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 자동 바인딩을 지원하는 View 기본 클래스
|
|
||||||
/// Attribute를 통해 설정된 바인딩을 자동으로 처리
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TViewModel">바인딩할 ViewModel 타입</typeparam>
|
|
||||||
public abstract class AutoBindView<TViewModel> : MonoBehaviour where TViewModel : SimpleViewModel
|
|
||||||
{
|
|
||||||
[SerializeField] protected TViewModel _viewModel;
|
|
||||||
protected BindingContext _bindingContext;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ViewModel 인스턴스
|
|
||||||
/// </summary>
|
|
||||||
public TViewModel ViewModel => _viewModel;
|
|
||||||
|
|
||||||
protected virtual void Awake()
|
|
||||||
{
|
|
||||||
if (_viewModel == null)
|
|
||||||
_viewModel = GetComponent<TViewModel>();
|
|
||||||
|
|
||||||
_bindingContext = new BindingContext();
|
|
||||||
|
|
||||||
SetupAutoBindings();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void OnEnable()
|
|
||||||
{
|
|
||||||
if (_viewModel != null && _bindingContext != null)
|
|
||||||
{
|
|
||||||
_bindingContext.SetDataContext(_viewModel);
|
|
||||||
_viewModel.PropertyChanged += OnViewModelPropertyChanged;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void OnDisable()
|
|
||||||
{
|
|
||||||
if (_viewModel != null)
|
|
||||||
{
|
|
||||||
_viewModel.PropertyChanged -= OnViewModelPropertyChanged;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void OnDestroy()
|
|
||||||
{
|
|
||||||
_bindingContext?.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Attribute 기반 자동 바인딩 설정
|
|
||||||
/// </summary>
|
|
||||||
private void SetupAutoBindings()
|
|
||||||
{
|
|
||||||
var fields = GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public)
|
|
||||||
.Where(f => f.GetCustomAttribute<BindToAttribute>() != null);
|
|
||||||
|
|
||||||
foreach (var field in fields)
|
|
||||||
{
|
|
||||||
var bindAttribute = field.GetCustomAttribute<BindToAttribute>();
|
|
||||||
SetupBinding(field, bindAttribute);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 컬렉션 바인딩 설정
|
|
||||||
var collectionFields = GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public)
|
|
||||||
.Where(f => f.GetCustomAttribute<BindCollectionAttribute>() != null);
|
|
||||||
|
|
||||||
foreach (var field in collectionFields)
|
|
||||||
{
|
|
||||||
var bindAttribute = field.GetCustomAttribute<BindCollectionAttribute>();
|
|
||||||
SetupCollectionBinding(field, bindAttribute);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 개별 필드의 바인딩 설정
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="field">바인딩할 필드</param>
|
|
||||||
/// <param name="bindAttribute">바인딩 Attribute</param>
|
|
||||||
private void SetupBinding(FieldInfo field, BindToAttribute bindAttribute)
|
|
||||||
{
|
|
||||||
var target = field.GetValue(this);
|
|
||||||
|
|
||||||
IValueConverter converter = null;
|
|
||||||
if (bindAttribute.ConverterType != null)
|
|
||||||
{
|
|
||||||
converter = Activator.CreateInstance(bindAttribute.ConverterType) as IValueConverter;
|
|
||||||
}
|
|
||||||
|
|
||||||
// UI 컴포넌트 타입별 바인딩 타겟 생성
|
|
||||||
IBindingTarget bindingTarget = target switch
|
|
||||||
{
|
|
||||||
Text text => new TextBindingTarget(text, bindAttribute.PropertyPath),
|
|
||||||
Image image => new ImageBindingTarget(image, bindAttribute.PropertyPath),
|
|
||||||
GameObject gameObject => new ActiveBindingTarget(gameObject, bindAttribute.PropertyPath),
|
|
||||||
Slider slider => new SliderBindingTarget(slider, bindAttribute.PropertyPath),
|
|
||||||
_ => null
|
|
||||||
};
|
|
||||||
|
|
||||||
if (bindingTarget != null)
|
|
||||||
{
|
|
||||||
_bindingContext.Bind(bindAttribute.PropertyPath, bindingTarget, converter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 컬렉션 바인딩 설정
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="field">바인딩할 필드</param>
|
|
||||||
/// <param name="bindAttribute">바인딩 Attribute</param>
|
|
||||||
private void SetupCollectionBinding(FieldInfo field, BindCollectionAttribute bindAttribute)
|
|
||||||
{
|
|
||||||
var target = field.GetValue(this);
|
|
||||||
|
|
||||||
if (target is Transform parent)
|
|
||||||
{
|
|
||||||
// 컬렉션 바인딩은 별도 구현이 필요한 복잡한 기능으로
|
|
||||||
// 현재는 기본 구조만 제공
|
|
||||||
Debug.Log($"Collection binding for {bindAttribute.PropertyPath} is set up on {parent.name}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ViewModel 속성 변경 이벤트 핸들러
|
|
||||||
/// 추가적인 커스텀 로직이 필요한 경우 오버라이드
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sender">이벤트 발신자</param>
|
|
||||||
/// <param name="e">속성 변경 정보</param>
|
|
||||||
protected virtual void OnViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
|
|
||||||
{
|
|
||||||
// 자동 바인딩으로 처리되지 않는 특별한 속성들의 커스텀 처리
|
|
||||||
HandleCustomPropertyChanged(e.PropertyName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 커스텀 속성 변경 처리 (하위 클래스에서 오버라이드)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="propertyName">변경된 속성 이름</param>
|
|
||||||
protected virtual void HandleCustomPropertyChanged(string propertyName)
|
|
||||||
{
|
|
||||||
// 하위 클래스에서 구현
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 수동 바인딩 헬퍼 메서드들
|
|
||||||
/// Attribute 사용이 어려운 경우 코드로 바인딩 설정
|
|
||||||
/// </summary>
|
|
||||||
|
|
||||||
protected void BindText(Text text, string propertyPath, IValueConverter converter = null)
|
|
||||||
{
|
|
||||||
var target = new TextBindingTarget(text, propertyPath);
|
|
||||||
_bindingContext?.Bind(propertyPath, target, converter);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void BindImage(Image image, string propertyPath, IValueConverter converter = null)
|
|
||||||
{
|
|
||||||
var target = new ImageBindingTarget(image, propertyPath);
|
|
||||||
_bindingContext?.Bind(propertyPath, target, converter);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void BindActive(GameObject gameObject, string propertyPath, IValueConverter converter = null)
|
|
||||||
{
|
|
||||||
var target = new ActiveBindingTarget(gameObject, propertyPath);
|
|
||||||
_bindingContext?.Bind(propertyPath, target, converter);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void BindSlider(Slider slider, string propertyPath, IValueConverter converter = null)
|
|
||||||
{
|
|
||||||
var target = new SliderBindingTarget(slider, propertyPath);
|
|
||||||
_bindingContext?.Bind(propertyPath, target, converter);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ViewModel 메서드 호출 헬퍼
|
|
||||||
/// UI 이벤트에서 ViewModel 메서드를 쉽게 호출
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="methodName">호출할 메서드 이름</param>
|
|
||||||
/// <param name="parameters">메서드 매개변수</param>
|
|
||||||
protected void InvokeViewModelMethod(string methodName, params object[] parameters)
|
|
||||||
{
|
|
||||||
if (_viewModel == null) return;
|
|
||||||
|
|
||||||
var method = _viewModel.GetType().GetMethod(methodName);
|
|
||||||
method?.Invoke(_viewModel, parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ViewModel 속성 직접 설정 헬퍼
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="propertyName">속성 이름</param>
|
|
||||||
/// <param name="value">설정할 값</param>
|
|
||||||
protected void SetViewModelProperty(string propertyName, object value)
|
|
||||||
{
|
|
||||||
if (_viewModel == null) return;
|
|
||||||
|
|
||||||
var property = _viewModel.GetType().GetProperty(propertyName);
|
|
||||||
if (property != null && property.CanWrite)
|
|
||||||
{
|
|
||||||
property.SetValue(_viewModel, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 738101122cf3fb74e99b244165797ab8
|
|
@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: abb1dd67b48daeb4f968a2641cf7b4a3
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
@ -5,7 +5,7 @@ namespace DDD
|
|||||||
{
|
{
|
||||||
public abstract class BasePopupUi : BaseUi
|
public abstract class BasePopupUi : BaseUi
|
||||||
{
|
{
|
||||||
public bool IsTopPopup => UiManager.Instance.PopupUiState.IsTopPopup(this);
|
public bool IsTopPopup => UiManager.Instance.UiState.IsTopPopup(this);
|
||||||
public InputActionMaps InputActionMaps;
|
public InputActionMaps InputActionMaps;
|
||||||
|
|
||||||
protected override void Awake()
|
protected override void Awake()
|
||||||
@ -29,10 +29,10 @@ protected override void Update()
|
|||||||
if (IsOpenPanel() == false) return;
|
if (IsOpenPanel() == false) return;
|
||||||
|
|
||||||
var currentSelectedGameObject = EventSystem.current.currentSelectedGameObject;
|
var currentSelectedGameObject = EventSystem.current.currentSelectedGameObject;
|
||||||
if (currentSelectedGameObject == null || currentSelectedGameObject.activeInHierarchy == false)
|
if (!currentSelectedGameObject || currentSelectedGameObject.activeInHierarchy == false)
|
||||||
{
|
{
|
||||||
var initialSelected = GetInitialSelected();
|
var initialSelected = GetInitialSelected();
|
||||||
if (initialSelected != null)
|
if (initialSelected)
|
||||||
{
|
{
|
||||||
EventSystem.current.SetSelectedGameObject(initialSelected);
|
EventSystem.current.SetSelectedGameObject(initialSelected);
|
||||||
}
|
}
|
||||||
@ -43,14 +43,14 @@ protected override void TryRegister()
|
|||||||
{
|
{
|
||||||
base.TryRegister();
|
base.TryRegister();
|
||||||
|
|
||||||
UiManager.Instance.PopupUiState?.RegisterPopupUI(this);
|
UiManager.Instance.UiState.RegisterPopupUI(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void TryUnregister()
|
protected override void TryUnregister()
|
||||||
{
|
{
|
||||||
base.TryUnregister();
|
base.TryUnregister();
|
||||||
|
|
||||||
UiManager.Instance?.PopupUiState?.UnregisterPopupUI(this);
|
UiManager.Instance?.UiState?.UnregisterPopupUI(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Open(OpenPopupUiEvent evt)
|
public virtual void Open(OpenPopupUiEvent evt)
|
||||||
|
@ -6,31 +6,47 @@
|
|||||||
|
|
||||||
namespace DDD
|
namespace DDD
|
||||||
{
|
{
|
||||||
[CreateAssetMenu(fileName = "PopupUiState", menuName = "GameUi/PopupUiState")]
|
public class UiState : SerializedScriptableObject, IEventHandler<OpenPopupUiEvent>, IEventHandler<ClosePopupUiEvent>
|
||||||
public class PopupUiState : SerializedScriptableObject, IEventHandler<OpenPopupUiEvent>, IEventHandler<ClosePopupUiEvent>
|
|
||||||
{
|
{
|
||||||
public Dictionary<GameFlowState, List<BasePopupUi>> FlowToPopupUiMapping = new();
|
private readonly Dictionary<Type, BaseUi> _uis = new();
|
||||||
|
|
||||||
|
private readonly Dictionary<Type, BasePopupUi> _popupUis = new();
|
||||||
|
private readonly Stack<BasePopupUi> _popupUiStack = new();
|
||||||
|
private InputActionMaps _previousActionMap = InputActionMaps.None;
|
||||||
|
|
||||||
|
private UiData _uiData => GameData.Instance.UiData;
|
||||||
|
|
||||||
|
public void OnEnable()
|
||||||
|
{
|
||||||
|
EventBus.Register<OpenPopupUiEvent>(this);
|
||||||
|
EventBus.Register<ClosePopupUiEvent>(this);
|
||||||
|
|
||||||
[Title("디버그")]
|
_uis.Clear();
|
||||||
[ReadOnly, ShowInInspector] private readonly Dictionary<Type, BasePopupUi> _popupUis = new();
|
_popupUis.Clear();
|
||||||
[ReadOnly, ShowInInspector] private readonly Stack<BasePopupUi> _popupUiStack = new();
|
_popupUiStack.Clear();
|
||||||
[ReadOnly, SerializeField] private InputActionMaps _previousActionMap = InputActionMaps.None;
|
}
|
||||||
|
|
||||||
private void OnDisable()
|
private void OnDisable()
|
||||||
{
|
{
|
||||||
EventBus.Unregister<OpenPopupUiEvent>(this);
|
EventBus.Unregister<OpenPopupUiEvent>(this);
|
||||||
EventBus.Unregister<ClosePopupUiEvent>(this);
|
EventBus.Unregister<ClosePopupUiEvent>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize()
|
public void RegisterUI(BaseUi ui)
|
||||||
{
|
{
|
||||||
EventBus.Register<OpenPopupUiEvent>(this);
|
var type = ui.GetType();
|
||||||
EventBus.Register<ClosePopupUiEvent>(this);
|
_uis.TryAdd(type, ui);
|
||||||
|
|
||||||
_popupUis.Clear();
|
|
||||||
_popupUiStack.Clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UnregisterUI(BaseUi ui)
|
||||||
|
{
|
||||||
|
var type = ui.GetType();
|
||||||
|
if (_uis.TryGetValue(type, out var registered) && registered == ui)
|
||||||
|
{
|
||||||
|
_uis.Remove(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void RegisterPopupUI(BasePopupUi ui)
|
public void RegisterPopupUI(BasePopupUi ui)
|
||||||
{
|
{
|
||||||
var type = ui.GetType();
|
var type = ui.GetType();
|
||||||
@ -85,51 +101,26 @@ public void Invoke(ClosePopupUiEvent evt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CreatePopup(BasePopupUi popup, Transform parent)
|
|
||||||
{
|
|
||||||
if (_popupUis.TryGetValue(popup.GetType(), out var registered) && registered == popup) return;
|
|
||||||
|
|
||||||
var instance = Instantiate(popup, parent);
|
|
||||||
instance.name = popup.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DestroyPopup(BasePopupUi popup)
|
|
||||||
{
|
|
||||||
if (_popupUis.TryGetValue(popup.GetType(), out var registered) == false || registered != popup) return;
|
|
||||||
|
|
||||||
Destroy(popup.gameObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<BasePopupUi> GetMatchingPopupUis(GameFlowState flowState)
|
|
||||||
{
|
|
||||||
return FlowToPopupUiMapping
|
|
||||||
.Where(keyValuePair => (keyValuePair.Key & flowState) != 0)
|
|
||||||
.SelectMany(keyValuePair => keyValuePair.Value)
|
|
||||||
.ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool HasMatchingPopupUis(GameFlowState flowState)
|
public bool HasMatchingPopupUis(GameFlowState flowState)
|
||||||
{
|
{
|
||||||
return FlowToPopupUiMapping.Any(keyValuePair => (keyValuePair.Key & flowState) != 0);
|
return _uiData.FlowToUiMapping.Any(keyValuePair => (keyValuePair.Key & flowState) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CreateMatchingPopupUis(GameFlowState flowState, Transform parent)
|
public void CreateUi(BaseUi ui, Transform parent)
|
||||||
{
|
{
|
||||||
var matchingPopupUis = GetMatchingPopupUis(flowState);
|
if (_uis.TryGetValue(ui.GetType(), out var registered) && registered == ui) return;
|
||||||
foreach (var popupUi in matchingPopupUis)
|
|
||||||
{
|
var instance = Instantiate(ui, parent);
|
||||||
CreatePopup(popupUi, parent);
|
instance.name = ui.name;
|
||||||
}
|
instance.CreateInitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DestroyMatchingPopupUis(GameFlowState flowState)
|
public void DestroyUi(BaseUi ui)
|
||||||
{
|
{
|
||||||
var matchingPopupUis = GetMatchingPopupUis(flowState);
|
if (_uis.TryGetValue(ui.GetType(), out var registered) && registered == ui) return;
|
||||||
foreach (var popupUi in matchingPopupUis)
|
|
||||||
{
|
Destroy(ui.gameObject);
|
||||||
DestroyPopup(popupUi);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsTopPopup(BasePopupUi popup)
|
public bool IsTopPopup(BasePopupUi popup)
|
||||||
|
@ -2,14 +2,9 @@
|
|||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using UnityEngine.EventSystems;
|
using UnityEngine.EventSystems;
|
||||||
using UnityEngine.InputSystem;
|
using UnityEngine.InputSystem;
|
||||||
using DDD.MVVM;
|
|
||||||
|
|
||||||
namespace DDD
|
namespace DDD
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// MVVM 패턴을 적용한 새로운 레스토랑 관리 UI
|
|
||||||
/// 기존 RestaurantManagementUi의 기능을 ViewModel과 분리하여 구현
|
|
||||||
/// </summary>
|
|
||||||
[RequireComponent(typeof(RestaurantManagementViewModel))]
|
[RequireComponent(typeof(RestaurantManagementViewModel))]
|
||||||
public class RestaurantManagementUi : PopupUi<RestaurantUiActions, RestaurantManagementViewModel>
|
public class RestaurantManagementUi : PopupUi<RestaurantUiActions, RestaurantManagementViewModel>
|
||||||
{
|
{
|
||||||
@ -26,26 +21,25 @@ public class RestaurantManagementUi : PopupUi<RestaurantUiActions, RestaurantMan
|
|||||||
[SerializeField] private TabGroupUi _cookwareCategoryTabs;
|
[SerializeField] private TabGroupUi _cookwareCategoryTabs;
|
||||||
|
|
||||||
[Header("Hold Progress UI")]
|
[Header("Hold Progress UI")]
|
||||||
[SerializeField, BindTo(nameof(RestaurantManagementViewModel.NormalizedHoldProgress))]
|
[SerializeField] private Image _completeBatchFilledImage;
|
||||||
private Image _completeBatchFilledImage;
|
|
||||||
|
|
||||||
protected override void Awake()
|
|
||||||
{
|
|
||||||
base.Awake();
|
|
||||||
|
|
||||||
SetupViewModelEvents();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
|
|
||||||
if (_viewModel != null && _viewModel.IsHolding)
|
if (_viewModel)
|
||||||
{
|
{
|
||||||
_viewModel.UpdateHoldProgress();
|
_viewModel.UpdateHoldProgress();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void TryRegister()
|
||||||
|
{
|
||||||
|
base.TryRegister();
|
||||||
|
|
||||||
|
SetupViewModelEvents();
|
||||||
|
}
|
||||||
|
|
||||||
public override void Open(OpenPopupUiEvent evt)
|
public override void Open(OpenPopupUiEvent evt)
|
||||||
{
|
{
|
||||||
base.Open(evt);
|
base.Open(evt);
|
||||||
@ -73,8 +67,7 @@ protected override GameObject GetInitialSelected()
|
|||||||
|
|
||||||
protected override void SetupBindings()
|
protected override void SetupBindings()
|
||||||
{
|
{
|
||||||
// Attribute 기반 자동 바인딩이 처리됨
|
BindingHelper.BindImageFilled(_bindingContext, _completeBatchFilledImage, nameof(RestaurantManagementViewModel.NormalizedHoldProgress));
|
||||||
// 추가적인 수동 바인딩이 필요한 경우 여기에 구현
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void HandleCustomPropertyChanged(string propertyName)
|
protected override void HandleCustomPropertyChanged(string propertyName)
|
||||||
@ -260,7 +253,7 @@ protected override bool OnInputCanceled(RestaurantUiActions actionEnum, InputAct
|
|||||||
{
|
{
|
||||||
var isHandled = base.OnInputCanceled(actionEnum, context);
|
var isHandled = base.OnInputCanceled(actionEnum, context);
|
||||||
|
|
||||||
if (isHandled && _viewModel != null)
|
if (isHandled && _viewModel)
|
||||||
{
|
{
|
||||||
switch (actionEnum)
|
switch (actionEnum)
|
||||||
{
|
{
|
||||||
|
7
Assets/_DDD/_Scripts/GameUi/RestaurantHud.cs
Normal file
7
Assets/_DDD/_Scripts/GameUi/RestaurantHud.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace DDD
|
||||||
|
{
|
||||||
|
public class RestaurantHud : BaseUi
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
2
Assets/_DDD/_Scripts/GameUi/RestaurantHud.cs.meta
Normal file
2
Assets/_DDD/_Scripts/GameUi/RestaurantHud.cs.meta
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7521841876f5b054aa4a0b0081ff8425
|
@ -1,390 +1,402 @@
|
|||||||
using System;
|
// using System;
|
||||||
using UnityEngine;
|
// using UnityEngine;
|
||||||
using UnityEngine.UI;
|
// using UnityEngine.UI;
|
||||||
using UnityEngine.EventSystems;
|
// using UnityEngine.EventSystems;
|
||||||
using UnityEngine.InputSystem;
|
// using UnityEngine.InputSystem;
|
||||||
|
//
|
||||||
namespace DDD
|
// namespace DDD
|
||||||
{
|
// {
|
||||||
public enum ButtonState
|
// public enum ButtonState
|
||||||
{
|
// {
|
||||||
Normal,
|
// Normal,
|
||||||
Highlighted,
|
// Highlighted,
|
||||||
Pressed,
|
// Pressed,
|
||||||
Selected,
|
// Selected,
|
||||||
Disabled
|
// Disabled
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public class UiButton : MonoBehaviour, IInteractableUi, IPointerEnterHandler, IPointerExitHandler,
|
// public enum ButtonType
|
||||||
IPointerDownHandler, IPointerUpHandler, ISelectHandler, IDeselectHandler, ISubmitHandler
|
// {
|
||||||
{
|
// None = 0,
|
||||||
[Header("Button Components")]
|
// Toggle
|
||||||
[SerializeField] private Button _button;
|
// }
|
||||||
[SerializeField] private Selectable _selectable;
|
//
|
||||||
|
// // TODO : ButtonType == None
|
||||||
[Header("State Synchronization")]
|
// // normal, selected(마우스 pointerEnter, eventsystem selected), pressed (마우스 pointerDown, 키보드 외부 입력처리), disabled
|
||||||
[SerializeField] private bool _synchronizeStates = true;
|
// // Highlighted가 사실상 selected로 통합, 실제로 마우스가 가리키는 오브젝트가 eventsystem의 selected가 됨
|
||||||
[SerializeField] private bool _handleKeyboardInput = true;
|
// // ButtonType == Toggle
|
||||||
[SerializeField] private bool _handleGamepadInput = true;
|
// // normal, highlighted, selected(계속 눌려있는 상태, 추후에 ToggleGroup 클래스에서 관리 - 다른 토글이 눌리기 전까지 풀리지 않음), pressed(눌리면 selected 고정), disabled
|
||||||
|
//
|
||||||
[Header("Visual Feedback")]
|
// public class UiButton : MonoBehaviour, IInteractableUi, IPointerEnterHandler, IPointerExitHandler,
|
||||||
[SerializeField] private Animator _animator;
|
// IPointerDownHandler, IPointerUpHandler, ISelectHandler, IDeselectHandler, ISubmitHandler
|
||||||
[SerializeField] private Image _targetGraphic;
|
// {
|
||||||
|
// [Header("Button Components")]
|
||||||
[Header("Toggle Functionality")]
|
// [SerializeField] private Button _button;
|
||||||
[SerializeField] private bool _useToggle = false;
|
// [SerializeField] private Selectable _selectable;
|
||||||
|
//
|
||||||
// State tracking
|
// [Header("State Synchronization")]
|
||||||
private bool _isPressed;
|
// [SerializeField] private bool _synchronizeStates = true;
|
||||||
private bool _isHighlighted;
|
// [SerializeField] private bool _handleKeyboardInput = true;
|
||||||
private bool _isSelected;
|
// [SerializeField] private bool _handleGamepadInput = true;
|
||||||
private bool _wasSelectedByKeyboard;
|
//
|
||||||
private bool _isToggled = false;
|
// [Header("Visual Feedback")]
|
||||||
|
// [SerializeField] private Animator _animator;
|
||||||
// Events
|
// [SerializeField] private Image _targetGraphic;
|
||||||
public event Action OnClicked;
|
//
|
||||||
public event Action OnStateChanged;
|
// [Header("Toggle Functionality")]
|
||||||
|
// [SerializeField] private ButtonType _buttonType;
|
||||||
// Animation parameter hashes (if using Animator)
|
//
|
||||||
private readonly int _normalHash = Animator.StringToHash("Normal");
|
// // State tracking
|
||||||
private readonly int _highlightedHash = Animator.StringToHash("Highlighted");
|
// private bool _isPressed;
|
||||||
private readonly int _pressedHash = Animator.StringToHash("Pressed");
|
// private bool _isHighlighted;
|
||||||
private readonly int _selectedHash = Animator.StringToHash("Selected");
|
// private bool _isSelected;
|
||||||
private readonly int _disabledHash = Animator.StringToHash("Disabled");
|
// private bool _wasSelectedByKeyboard;
|
||||||
|
// private bool _isToggled = false;
|
||||||
private void Awake()
|
//
|
||||||
{
|
// // Events
|
||||||
InitializeComponents();
|
// public event Action OnClicked;
|
||||||
}
|
// public event Action OnStateChanged;
|
||||||
|
//
|
||||||
private void OnEnable()
|
// // Animation parameter hashes (if using Animator)
|
||||||
{
|
// private readonly int _normalHash = Animator.StringToHash("Normal");
|
||||||
if (_button != null)
|
// private readonly int _highlightedHash = Animator.StringToHash("Highlighted");
|
||||||
{
|
// private readonly int _pressedHash = Animator.StringToHash("Pressed");
|
||||||
_button.onClick.AddListener(HandleButtonClick);
|
// private readonly int _selectedHash = Animator.StringToHash("Selected");
|
||||||
}
|
// private readonly int _disabledHash = Animator.StringToHash("Disabled");
|
||||||
|
//
|
||||||
UpdateVisualState();
|
// private void Awake()
|
||||||
}
|
// {
|
||||||
|
// InitializeComponents();
|
||||||
private void OnDisable()
|
// }
|
||||||
{
|
//
|
||||||
if (_button != null)
|
// private void OnEnable()
|
||||||
{
|
// {
|
||||||
_button.onClick.RemoveListener(HandleButtonClick);
|
// if (_button != null)
|
||||||
}
|
// {
|
||||||
}
|
// _button.onClick.AddListener(HandleButtonClick);
|
||||||
|
// }
|
||||||
private void Update()
|
//
|
||||||
{
|
// UpdateVisualState();
|
||||||
HandleInputUpdate();
|
// }
|
||||||
}
|
//
|
||||||
|
// private void OnDisable()
|
||||||
private void InitializeComponents()
|
// {
|
||||||
{
|
// if (_button != null)
|
||||||
// Get Button component if not assigned
|
// {
|
||||||
if (_button == null)
|
// _button.onClick.RemoveListener(HandleButtonClick);
|
||||||
{
|
// }
|
||||||
_button = GetComponent<Button>();
|
// }
|
||||||
}
|
//
|
||||||
|
// private void Update()
|
||||||
// Get Selectable component (Button inherits from Selectable)
|
// {
|
||||||
if (_selectable == null)
|
// HandleInputUpdate();
|
||||||
{
|
// }
|
||||||
_selectable = _button;
|
//
|
||||||
}
|
// private void InitializeComponents()
|
||||||
|
// {
|
||||||
// Get target graphic from button if not assigned
|
// // Get Button component if not assigned
|
||||||
if (_targetGraphic == null && _button != null)
|
// if (_button == null)
|
||||||
{
|
// {
|
||||||
_targetGraphic = _button.targetGraphic as Image;
|
// _button = GetComponent<Button>();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// Get Animator if not assigned
|
// // Get Selectable component (Button inherits from Selectable)
|
||||||
if (_animator == null)
|
// if (_selectable == null)
|
||||||
{
|
// {
|
||||||
_animator = GetComponent<Animator>();
|
// _selectable = _button;
|
||||||
}
|
// }
|
||||||
}
|
//
|
||||||
|
// // Get target graphic from button if not assigned
|
||||||
private void HandleInputUpdate()
|
// if (_targetGraphic == null && _button != null)
|
||||||
{
|
// {
|
||||||
if (!_handleKeyboardInput && !_handleGamepadInput) return;
|
// _targetGraphic = _button.targetGraphic as Image;
|
||||||
if (_selectable == null || !_selectable.interactable) return;
|
// }
|
||||||
|
//
|
||||||
// Handle keyboard/gamepad input when this button is selected
|
// // Get Animator if not assigned
|
||||||
if (EventSystem.current != null && EventSystem.current.currentSelectedGameObject == gameObject)
|
// if (_animator == null)
|
||||||
{
|
// {
|
||||||
//HandleSelectedInput();
|
// _animator = GetComponent<Animator>();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private void HandleSelectedInput()
|
// private void HandleInputUpdate()
|
||||||
{
|
// {
|
||||||
var keyboard = Keyboard.current;
|
// if (!_handleKeyboardInput && !_handleGamepadInput) return;
|
||||||
var gamepad = Gamepad.current;
|
// if (_selectable == null || !_selectable.interactable) return;
|
||||||
|
//
|
||||||
// Handle keyboard input
|
// // Handle keyboard/gamepad input when this button is selected
|
||||||
if (_handleKeyboardInput && keyboard != null)
|
// if (EventSystem.current != null && EventSystem.current.currentSelectedGameObject == gameObject)
|
||||||
{
|
// {
|
||||||
if (keyboard.enterKey.wasPressedThisFrame || keyboard.spaceKey.wasPressedThisFrame)
|
// //HandleSelectedInput();
|
||||||
{
|
// }
|
||||||
HandleButtonClick();
|
// }
|
||||||
}
|
//
|
||||||
}
|
// private void HandleSelectedInput()
|
||||||
|
// {
|
||||||
// Handle gamepad input
|
// var keyboard = Keyboard.current;
|
||||||
if (_handleGamepadInput && gamepad != null)
|
// var gamepad = Gamepad.current;
|
||||||
{
|
//
|
||||||
if (gamepad.buttonSouth.wasPressedThisFrame) // A button on Xbox controller
|
// // Handle keyboard input
|
||||||
{
|
// if (_handleKeyboardInput && keyboard != null)
|
||||||
HandleButtonClick();
|
// {
|
||||||
}
|
// if (keyboard.enterKey.wasPressedThisFrame || keyboard.spaceKey.wasPressedThisFrame)
|
||||||
}
|
// {
|
||||||
}
|
// HandleButtonClick();
|
||||||
|
// }
|
||||||
private void HandleButtonClick()
|
// }
|
||||||
{
|
//
|
||||||
if (_selectable != null && !_selectable.interactable) return;
|
// // Handle gamepad input
|
||||||
|
// if (_handleGamepadInput && gamepad != null)
|
||||||
if (_useToggle)
|
// {
|
||||||
{
|
// if (gamepad.buttonSouth.wasPressedThisFrame) // A button on Xbox controller
|
||||||
_isToggled = !_isToggled;
|
// {
|
||||||
|
// HandleButtonClick();
|
||||||
if (_isToggled)
|
// }
|
||||||
{
|
// }
|
||||||
// When toggled on, maintain pressed state and make non-interactable
|
// }
|
||||||
_isPressed = true;
|
//
|
||||||
_selectable.interactable = false;
|
// private void HandleButtonClick()
|
||||||
}
|
// {
|
||||||
else
|
// if (_selectable != null && !_selectable.interactable) return;
|
||||||
{
|
//
|
||||||
// When toggled off, restore normal behavior
|
// if (_buttonType == ButtonType.Toggle)
|
||||||
_isPressed = false;
|
// {
|
||||||
_selectable.interactable = true;
|
// _isToggled = !_isToggled;
|
||||||
}
|
//
|
||||||
|
// if (_isToggled)
|
||||||
UpdateVisualState();
|
// {
|
||||||
}
|
// // When toggled on, maintain pressed state and make non-interactable
|
||||||
|
// _isPressed = true;
|
||||||
OnClicked?.Invoke();
|
// _selectable.interactable = false;
|
||||||
}
|
// }
|
||||||
|
// else
|
||||||
private void UpdateVisualState()
|
// {
|
||||||
{
|
// // When toggled off, restore normal behavior
|
||||||
if (!_synchronizeStates) return;
|
// _isPressed = false;
|
||||||
|
// _selectable.interactable = true;
|
||||||
var currentState = GetCurrentState();
|
// }
|
||||||
print(currentState);
|
//
|
||||||
ApplyVisualState(currentState);
|
// UpdateVisualState();
|
||||||
OnStateChanged?.Invoke();
|
// }
|
||||||
}
|
//
|
||||||
|
// OnClicked?.Invoke();
|
||||||
private ButtonState GetCurrentState()
|
// }
|
||||||
{
|
//
|
||||||
if (_selectable == null || (!_selectable.interactable && !_isToggled))
|
// private void UpdateVisualState()
|
||||||
return ButtonState.Disabled;
|
// {
|
||||||
|
// if (!_synchronizeStates) return;
|
||||||
// Toggle mode: when toggled on, maintain pressed state even if not interactable
|
//
|
||||||
if (_useToggle && _isToggled)
|
// var currentState = GetCurrentState();
|
||||||
return ButtonState.Pressed;
|
// print(currentState);
|
||||||
|
// ApplyVisualState(currentState);
|
||||||
if (_isPressed)
|
// OnStateChanged?.Invoke();
|
||||||
return ButtonState.Pressed;
|
// }
|
||||||
|
//
|
||||||
if (_isSelected)
|
// private ButtonState GetCurrentState()
|
||||||
return ButtonState.Selected;
|
// {
|
||||||
|
// if (_selectable == null || (!_selectable.interactable && !_isToggled))
|
||||||
if (_isHighlighted)
|
// return ButtonState.Disabled;
|
||||||
return ButtonState.Highlighted;
|
//
|
||||||
|
// // Toggle mode: when toggled on, maintain pressed state even if not interactable
|
||||||
return ButtonState.Normal;
|
// if (_useToggle && _isToggled)
|
||||||
}
|
// return ButtonState.Pressed;
|
||||||
|
//
|
||||||
private void ApplyVisualState(ButtonState state)
|
// if (_isPressed)
|
||||||
{
|
// return ButtonState.Pressed;
|
||||||
// Apply animator state if available
|
//
|
||||||
if (_animator != null && _animator.runtimeAnimatorController != null)
|
// if (_isSelected)
|
||||||
{
|
// return ButtonState.Selected;
|
||||||
ApplyAnimatorState(state);
|
//
|
||||||
}
|
// if (_isHighlighted)
|
||||||
|
// return ButtonState.Highlighted;
|
||||||
// Apply color tint if using Button's color block
|
//
|
||||||
if (_button != null && _targetGraphic != null)
|
// return ButtonState.Normal;
|
||||||
{
|
// }
|
||||||
ApplyColorState(state);
|
//
|
||||||
}
|
// private void ApplyVisualState(ButtonState state)
|
||||||
}
|
// {
|
||||||
|
// // Apply animator state if available
|
||||||
private void ApplyAnimatorState(ButtonState state)
|
// if (_animator != null && _animator.runtimeAnimatorController != null)
|
||||||
{
|
// {
|
||||||
switch (state)
|
// ApplyAnimatorState(state);
|
||||||
{
|
// }
|
||||||
case ButtonState.Normal:
|
//
|
||||||
_animator.SetTrigger(_normalHash);
|
// // Apply color tint if using Button's color block
|
||||||
break;
|
// if (_button != null && _targetGraphic != null)
|
||||||
case ButtonState.Highlighted:
|
// {
|
||||||
_animator.SetTrigger(_highlightedHash);
|
// ApplyColorState(state);
|
||||||
break;
|
// }
|
||||||
case ButtonState.Pressed:
|
// }
|
||||||
_animator.SetTrigger(_pressedHash);
|
//
|
||||||
break;
|
// private void ApplyAnimatorState(ButtonState state)
|
||||||
case ButtonState.Selected:
|
// {
|
||||||
_animator.SetTrigger(_selectedHash);
|
// switch (state)
|
||||||
break;
|
// {
|
||||||
case ButtonState.Disabled:
|
// case ButtonState.Normal:
|
||||||
_animator.SetTrigger(_disabledHash);
|
// _animator.SetTrigger(_normalHash);
|
||||||
break;
|
// break;
|
||||||
}
|
// case ButtonState.Highlighted:
|
||||||
}
|
// _animator.SetTrigger(_highlightedHash);
|
||||||
|
// break;
|
||||||
private void ApplyColorState(ButtonState state)
|
// case ButtonState.Pressed:
|
||||||
{
|
// _animator.SetTrigger(_pressedHash);
|
||||||
var colors = _button.colors;
|
// break;
|
||||||
Color targetColor;
|
// case ButtonState.Selected:
|
||||||
|
// _animator.SetTrigger(_selectedHash);
|
||||||
switch (state)
|
// break;
|
||||||
{
|
// case ButtonState.Disabled:
|
||||||
case ButtonState.Normal:
|
// _animator.SetTrigger(_disabledHash);
|
||||||
targetColor = colors.normalColor;
|
// break;
|
||||||
break;
|
// }
|
||||||
case ButtonState.Highlighted:
|
// }
|
||||||
targetColor = colors.highlightedColor;
|
//
|
||||||
break;
|
// private void ApplyColorState(ButtonState state)
|
||||||
case ButtonState.Pressed:
|
// {
|
||||||
targetColor = colors.pressedColor;
|
// var colors = _button.colors;
|
||||||
break;
|
// Color targetColor;
|
||||||
case ButtonState.Selected:
|
//
|
||||||
targetColor = colors.selectedColor;
|
// switch (state)
|
||||||
break;
|
// {
|
||||||
case ButtonState.Disabled:
|
// case ButtonState.Normal:
|
||||||
targetColor = colors.disabledColor;
|
// targetColor = colors.normalColor;
|
||||||
break;
|
// break;
|
||||||
default:
|
// case ButtonState.Highlighted:
|
||||||
targetColor = colors.normalColor;
|
// targetColor = colors.highlightedColor;
|
||||||
break;
|
// break;
|
||||||
}
|
// case ButtonState.Pressed:
|
||||||
|
// targetColor = colors.pressedColor;
|
||||||
_targetGraphic.color = targetColor;
|
// break;
|
||||||
}
|
// case ButtonState.Selected:
|
||||||
|
// targetColor = colors.selectedColor;
|
||||||
// IInteractableUi implementation
|
// break;
|
||||||
public void OnInteract()
|
// case ButtonState.Disabled:
|
||||||
{
|
// targetColor = colors.disabledColor;
|
||||||
if (_selectable != null && _selectable.interactable)
|
// break;
|
||||||
{
|
// default:
|
||||||
// This method is called for programmatic interaction
|
// targetColor = colors.normalColor;
|
||||||
HandleButtonClick();
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
//
|
||||||
|
// _targetGraphic.color = targetColor;
|
||||||
// Pointer event handlers
|
// }
|
||||||
public void OnPointerEnter(PointerEventData eventData)
|
//
|
||||||
{
|
// // IInteractableUi implementation
|
||||||
_isHighlighted = true;
|
// public void OnInteract()
|
||||||
UpdateVisualState();
|
// {
|
||||||
}
|
// if (_selectable != null && _selectable.interactable)
|
||||||
|
// {
|
||||||
public void OnPointerExit(PointerEventData eventData)
|
// // This method is called for programmatic interaction
|
||||||
{
|
// HandleButtonClick();
|
||||||
_isHighlighted = false;
|
// }
|
||||||
UpdateVisualState();
|
// }
|
||||||
}
|
//
|
||||||
|
// // Pointer event handlers
|
||||||
public void OnPointerDown(PointerEventData eventData)
|
// public void OnPointerEnter(PointerEventData eventData)
|
||||||
{
|
// {
|
||||||
if (eventData.button == PointerEventData.InputButton.Left)
|
// _isHighlighted = true;
|
||||||
{
|
// UpdateVisualState();
|
||||||
if (_isSelected)
|
// }
|
||||||
{
|
//
|
||||||
_isPressed = true;
|
// public void OnPointerExit(PointerEventData eventData)
|
||||||
UpdateVisualState();
|
// {
|
||||||
return;
|
// _isHighlighted = false;
|
||||||
}
|
// UpdateVisualState();
|
||||||
_isSelected = true;
|
// }
|
||||||
UpdateVisualState();
|
//
|
||||||
}
|
// public void OnPointerDown(PointerEventData eventData)
|
||||||
}
|
// {
|
||||||
|
// if (eventData.button == PointerEventData.InputButton.Left)
|
||||||
public void OnPointerUp(PointerEventData eventData)
|
// {
|
||||||
{
|
// if (_isSelected)
|
||||||
if (eventData.button == PointerEventData.InputButton.Left)
|
// {
|
||||||
{
|
// _isPressed = true;
|
||||||
// Don't reset pressed state in toggle mode when toggled on
|
// UpdateVisualState();
|
||||||
if (_isPressed && !(_useToggle && _isToggled))
|
// return;
|
||||||
{
|
// }
|
||||||
_isPressed = false;
|
// _isSelected = true;
|
||||||
}
|
// UpdateVisualState();
|
||||||
_isSelected = false;
|
// }
|
||||||
UpdateVisualState();
|
// }
|
||||||
}
|
//
|
||||||
}
|
// public void OnPointerUp(PointerEventData eventData)
|
||||||
|
// {
|
||||||
// Selection event handlers (for keyboard/gamepad navigation)
|
// if (eventData.button == PointerEventData.InputButton.Left)
|
||||||
public void OnSelect(BaseEventData eventData)
|
// {
|
||||||
{
|
// // Don't reset pressed state in toggle mode when toggled on
|
||||||
_isSelected = true;
|
// if (_isPressed && !(_useToggle && _isToggled))
|
||||||
UpdateVisualState();
|
// {
|
||||||
}
|
// _isPressed = false;
|
||||||
|
// }
|
||||||
public void OnDeselect(BaseEventData eventData)
|
// _isSelected = false;
|
||||||
{
|
// UpdateVisualState();
|
||||||
_isSelected = false;
|
// }
|
||||||
UpdateVisualState();
|
// }
|
||||||
}
|
//
|
||||||
|
// // Selection event handlers (for keyboard/gamepad navigation)
|
||||||
// Submit handler (for keyboard/gamepad activation)
|
// public void OnSelect(BaseEventData eventData)
|
||||||
public void OnSubmit(BaseEventData eventData)
|
// {
|
||||||
{
|
// _isSelected = true;
|
||||||
HandleButtonClick();
|
// UpdateVisualState();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// Public API
|
// public void OnDeselect(BaseEventData eventData)
|
||||||
public bool IsInteractable => _selectable != null && _selectable.interactable;
|
// {
|
||||||
|
// _isSelected = false;
|
||||||
public void SetInteractable(bool interactable)
|
// UpdateVisualState();
|
||||||
{
|
// }
|
||||||
if (_selectable != null)
|
//
|
||||||
{
|
// // Submit handler (for keyboard/gamepad activation)
|
||||||
_selectable.interactable = interactable;
|
// public void OnSubmit(BaseEventData eventData)
|
||||||
UpdateVisualState();
|
// {
|
||||||
}
|
// HandleButtonClick();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public void ForceUpdateState()
|
// // Public API
|
||||||
{
|
// public bool IsInteractable => _selectable != null && _selectable.interactable;
|
||||||
UpdateVisualState();
|
//
|
||||||
}
|
// public void SetInteractable(bool interactable)
|
||||||
|
// {
|
||||||
// Toggle functionality API
|
// if (_selectable != null)
|
||||||
public bool UseToggle
|
// {
|
||||||
{
|
// _selectable.interactable = interactable;
|
||||||
get => _useToggle;
|
// UpdateVisualState();
|
||||||
set => _useToggle = value;
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public bool IsToggled => _isToggled;
|
// public void ForceUpdateState()
|
||||||
|
// {
|
||||||
public void SetToggleState(bool toggled)
|
// UpdateVisualState();
|
||||||
{
|
// }
|
||||||
if (!_useToggle) return;
|
//
|
||||||
|
// // Toggle functionality API
|
||||||
_isToggled = toggled;
|
// public bool UseToggle
|
||||||
|
// {
|
||||||
if (_isToggled)
|
// get => _useToggle;
|
||||||
{
|
// set => _useToggle = value;
|
||||||
_isPressed = true;
|
// }
|
||||||
if (_selectable != null)
|
//
|
||||||
_selectable.interactable = false;
|
// public bool IsToggled => _isToggled;
|
||||||
}
|
//
|
||||||
else
|
// public void SetToggleState(bool toggled)
|
||||||
{
|
// {
|
||||||
_isPressed = false;
|
// if (!_useToggle) return;
|
||||||
if (_selectable != null)
|
//
|
||||||
_selectable.interactable = true;
|
// _isToggled = toggled;
|
||||||
}
|
//
|
||||||
|
// if (_isToggled)
|
||||||
UpdateVisualState();
|
// {
|
||||||
}
|
// _isPressed = true;
|
||||||
}
|
// if (_selectable != null)
|
||||||
}
|
// _selectable.interactable = false;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// _isPressed = false;
|
||||||
|
// if (_selectable != null)
|
||||||
|
// _selectable.interactable = true;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// UpdateVisualState();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
@ -1,133 +0,0 @@
|
|||||||
using UnityEngine;
|
|
||||||
using UnityEngine.UI;
|
|
||||||
|
|
||||||
namespace DDD
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Simple test script to verify UiButton functionality.
|
|
||||||
/// Attach this to a GameObject with UiButton component to test.
|
|
||||||
/// </summary>
|
|
||||||
public class UiButtonTest : MonoBehaviour
|
|
||||||
{
|
|
||||||
[SerializeField] private UiButton _uiButton;
|
|
||||||
[SerializeField] private Text _statusText;
|
|
||||||
|
|
||||||
private int _clickCount = 0;
|
|
||||||
|
|
||||||
private void Start()
|
|
||||||
{
|
|
||||||
// Get UiButton if not assigned
|
|
||||||
if (_uiButton == null)
|
|
||||||
{
|
|
||||||
_uiButton = GetComponent<UiButton>();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_uiButton != null)
|
|
||||||
{
|
|
||||||
// Subscribe to events
|
|
||||||
_uiButton.OnClicked += HandleButtonClicked;
|
|
||||||
_uiButton.OnStateChanged += HandleStateChanged;
|
|
||||||
|
|
||||||
Debug.Log("[DEBUG_LOG] UiButton test initialized");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Debug.LogError("[DEBUG_LOG] UiButton component not found!");
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateStatusText();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnDestroy()
|
|
||||||
{
|
|
||||||
if (_uiButton != null)
|
|
||||||
{
|
|
||||||
_uiButton.OnClicked -= HandleButtonClicked;
|
|
||||||
_uiButton.OnStateChanged -= HandleStateChanged;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HandleButtonClicked()
|
|
||||||
{
|
|
||||||
_clickCount++;
|
|
||||||
Debug.Log($"[DEBUG_LOG] UiButton clicked! Count: {_clickCount}");
|
|
||||||
UpdateStatusText();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HandleStateChanged()
|
|
||||||
{
|
|
||||||
Debug.Log($"[DEBUG_LOG] UiButton state changed. Interactable: {_uiButton.IsInteractable}");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateStatusText()
|
|
||||||
{
|
|
||||||
if (_statusText != null)
|
|
||||||
{
|
|
||||||
_statusText.text = $"Clicks: {_clickCount}\nInteractable: {(_uiButton?.IsInteractable ?? false)}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test methods that can be called from inspector or other scripts
|
|
||||||
[ContextMenu("Toggle Interactable")]
|
|
||||||
public void ToggleInteractable()
|
|
||||||
{
|
|
||||||
if (_uiButton != null)
|
|
||||||
{
|
|
||||||
_uiButton.SetInteractable(!_uiButton.IsInteractable);
|
|
||||||
Debug.Log($"[DEBUG_LOG] Button interactable set to: {_uiButton.IsInteractable}");
|
|
||||||
UpdateStatusText();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[ContextMenu("Force Update State")]
|
|
||||||
public void ForceUpdateState()
|
|
||||||
{
|
|
||||||
if (_uiButton != null)
|
|
||||||
{
|
|
||||||
_uiButton.ForceUpdateState();
|
|
||||||
Debug.Log("[DEBUG_LOG] Button state forcefully updated");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[ContextMenu("Reset Click Count")]
|
|
||||||
public void ResetClickCount()
|
|
||||||
{
|
|
||||||
_clickCount = 0;
|
|
||||||
Debug.Log("[DEBUG_LOG] Click count reset");
|
|
||||||
UpdateStatusText();
|
|
||||||
}
|
|
||||||
|
|
||||||
[ContextMenu("Toggle Use Toggle Mode")]
|
|
||||||
public void ToggleUseToggleMode()
|
|
||||||
{
|
|
||||||
if (_uiButton != null)
|
|
||||||
{
|
|
||||||
_uiButton.UseToggle = !_uiButton.UseToggle;
|
|
||||||
Debug.Log($"[DEBUG_LOG] Toggle mode set to: {_uiButton.UseToggle}");
|
|
||||||
UpdateStatusText();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[ContextMenu("Set Toggle State On")]
|
|
||||||
public void SetToggleStateOn()
|
|
||||||
{
|
|
||||||
if (_uiButton != null)
|
|
||||||
{
|
|
||||||
_uiButton.SetToggleState(true);
|
|
||||||
Debug.Log($"[DEBUG_LOG] Toggle state set to ON. Toggled: {_uiButton.IsToggled}");
|
|
||||||
UpdateStatusText();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[ContextMenu("Set Toggle State Off")]
|
|
||||||
public void SetToggleStateOff()
|
|
||||||
{
|
|
||||||
if (_uiButton != null)
|
|
||||||
{
|
|
||||||
_uiButton.SetToggleState(false);
|
|
||||||
Debug.Log($"[DEBUG_LOG] Toggle state set to OFF. Toggled: {_uiButton.IsToggled}");
|
|
||||||
UpdateStatusText();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: cc3aec81f35244d39191739b3bd208d2
|
|
||||||
timeCreated: 1755681789
|
|
@ -1,15 +1,18 @@
|
|||||||
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.AddressableAssets;
|
|
||||||
|
|
||||||
namespace DDD
|
namespace DDD
|
||||||
{
|
{
|
||||||
public class UiManager : Singleton<UiManager>, IManager, IGameFlowHandler
|
public class UiManager : Singleton<UiManager>, IManager, IGameFlowHandler
|
||||||
{
|
{
|
||||||
[SerializeField] private AssetReference _popupUiState;
|
[SerializeField] private Transform _hudRoot;
|
||||||
|
[SerializeField] private Transform _interactionUiRoot;
|
||||||
[SerializeField] private Transform _popupUiRoot;
|
[SerializeField] private Transform _popupUiRoot;
|
||||||
|
[SerializeField] private Transform _commonUiRoot;
|
||||||
|
|
||||||
public PopupUiState PopupUiState { get; private set; }
|
public UiData UiData => GameData.Instance.UiData;
|
||||||
|
public UiState UiState => GameState.Instance.UiState;
|
||||||
|
|
||||||
private void OnDestroy()
|
private void OnDestroy()
|
||||||
{
|
{
|
||||||
@ -18,17 +21,28 @@ private void OnDestroy()
|
|||||||
|
|
||||||
public void PreInit()
|
public void PreInit()
|
||||||
{
|
{
|
||||||
|
ClearAll();
|
||||||
|
|
||||||
GameFlowManager.Instance.FlowHandlers.Add(this);
|
GameFlowManager.Instance.FlowHandlers.Add(this);
|
||||||
|
|
||||||
foreach (Transform child in _popupUiRoot)
|
|
||||||
{
|
|
||||||
Destroy(child.gameObject);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Init()
|
public Task Init()
|
||||||
{
|
{
|
||||||
await LoadData();
|
var flowToUiMapping = UiData.FlowToUiMapping;
|
||||||
|
foreach (var flowToUis in flowToUiMapping)
|
||||||
|
{
|
||||||
|
if (flowToUis.Key == GameFlowState.All)
|
||||||
|
{
|
||||||
|
foreach (var ui in flowToUis.Value)
|
||||||
|
{
|
||||||
|
var uiType = ui.UiType;
|
||||||
|
var root = GetUiRoot(uiType);
|
||||||
|
UiState.CreateUi(ui, root);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PostInit()
|
public void PostInit()
|
||||||
@ -36,27 +50,62 @@ public void PostInit()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ClearObjects(Transform root)
|
||||||
|
{
|
||||||
|
foreach (Transform child in root)
|
||||||
|
{
|
||||||
|
Destroy(child.gameObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClearAll()
|
||||||
|
{
|
||||||
|
ClearObjects(_hudRoot);
|
||||||
|
ClearObjects(_interactionUiRoot);
|
||||||
|
ClearObjects(_popupUiRoot);
|
||||||
|
ClearObjects(_commonUiRoot);
|
||||||
|
}
|
||||||
|
|
||||||
public Task OnReadyNewFlow(GameFlowState newFlowState)
|
public Task OnReadyNewFlow(GameFlowState newFlowState)
|
||||||
{
|
{
|
||||||
PopupUiState.CreateMatchingPopupUis(newFlowState, _popupUiRoot);
|
var flowToUiMapping = UiData.FlowToUiMapping;
|
||||||
|
foreach (var flowToUis in flowToUiMapping)
|
||||||
|
{
|
||||||
|
if ((flowToUis.Key & newFlowState) != 0)
|
||||||
|
{
|
||||||
|
foreach (var ui in flowToUis.Value)
|
||||||
|
{
|
||||||
|
var uiType = ui.UiType;
|
||||||
|
var root = GetUiRoot(uiType);
|
||||||
|
UiState.CreateUi(ui, root);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (var ui in flowToUis.Value)
|
||||||
|
{
|
||||||
|
UiState.DestroyUi(ui);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task OnExitCurrentFlow(GameFlowState exitingFlowState)
|
public Task OnExitCurrentFlow(GameFlowState exitingFlowState)
|
||||||
{
|
{
|
||||||
PopupUiState.DestroyMatchingPopupUis(exitingFlowState);
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task LoadData()
|
public Transform GetUiRoot(UiType uiType)
|
||||||
{
|
{
|
||||||
var handle = _popupUiState.LoadAssetAsync<PopupUiState>();
|
return uiType switch
|
||||||
await handle.Task;
|
{
|
||||||
PopupUiState = handle.Result;
|
UiType.Hud => _hudRoot,
|
||||||
|
UiType.Interaction => _interactionUiRoot,
|
||||||
Debug.Assert(PopupUiState != null, "PopupUiState is null");
|
UiType.Popup => _popupUiRoot,
|
||||||
|
UiType.Common => _commonUiRoot,
|
||||||
PopupUiState.Initialize();
|
_ => throw new Exception("UiType 설정 오류")
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user