Revamp game pausing and input handling. Fix minigame tutorial and end sequence. (#39)
- Revamp pausing and centralize management in GameManager - Switch Pause implementation to be counter-based to solve corner case of multiple pause requests - Remove duplicated Pause logic from other components - Add pausing when browsing the card album - Fully deliver the exclusive UI implementation - Spruce up the MiniGame tutorial with correct pausing, hiding other UI - Correctly unpause after showing tutorial - Fix minigame ending sequence. The cinematic correctly plays only once now - Replaying the minigame works Co-authored-by: Michal Adam Pikulski <michal@foolhardyhorizons.com> Co-authored-by: Michal Pikulski <michal@foolhardyhorizons.com> Reviewed-on: #39
This commit is contained in:
@@ -299,7 +299,7 @@ GameObject:
|
|||||||
m_Component:
|
m_Component:
|
||||||
- component: {fileID: 8855931927481658112}
|
- component: {fileID: 8855931927481658112}
|
||||||
- component: {fileID: 5244731468946939147}
|
- component: {fileID: 5244731468946939147}
|
||||||
- component: {fileID: 2860077094930428643}
|
- component: {fileID: 7848685733999064403}
|
||||||
m_Layer: 5
|
m_Layer: 5
|
||||||
m_Name: Backback
|
m_Name: Backback
|
||||||
m_TagString: Untagged
|
m_TagString: Untagged
|
||||||
@@ -372,7 +372,7 @@ MonoBehaviour:
|
|||||||
m_OnClick:
|
m_OnClick:
|
||||||
m_PersistentCalls:
|
m_PersistentCalls:
|
||||||
m_Calls: []
|
m_Calls: []
|
||||||
--- !u!114 &2860077094930428643
|
--- !u!114 &7848685733999064403
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
@@ -381,9 +381,9 @@ MonoBehaviour:
|
|||||||
m_GameObject: {fileID: 7564017895147059150}
|
m_GameObject: {fileID: 7564017895147059150}
|
||||||
m_Enabled: 1
|
m_Enabled: 1
|
||||||
m_EditorHideFlags: 0
|
m_EditorHideFlags: 0
|
||||||
m_Script: {fileID: 11500000, guid: e7ea50a695c58944799b4f27a9014301, type: 3}
|
m_Script: {fileID: 11500000, guid: 494d0aedce9744308499355006071138, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier: '::'
|
m_EditorClassIdentifier: AppleHillsScripts::UI.DummyInput
|
||||||
--- !u!1 &8561999612656273135
|
--- !u!1 &8561999612656273135
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
|||||||
@@ -75,6 +75,135 @@ MonoBehaviour:
|
|||||||
m_FillOrigin: 0
|
m_FillOrigin: 0
|
||||||
m_UseSpriteMesh: 0
|
m_UseSpriteMesh: 0
|
||||||
m_PixelsPerUnitMultiplier: 1
|
m_PixelsPerUnitMultiplier: 1
|
||||||
|
--- !u!1 &1188952073410115051
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 4893439260580271593}
|
||||||
|
- component: {fileID: 2903185199836080833}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: TutorialAudio
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!4 &4893439260580271593
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1188952073410115051}
|
||||||
|
serializedVersion: 2
|
||||||
|
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||||
|
m_LocalPosition: {x: -80.867836, y: 74.80073, z: 0}
|
||||||
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
|
m_ConstrainProportionsScale: 0
|
||||||
|
m_Children: []
|
||||||
|
m_Father: {fileID: 3183207532655435649}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!82 &2903185199836080833
|
||||||
|
AudioSource:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1188952073410115051}
|
||||||
|
m_Enabled: 1
|
||||||
|
serializedVersion: 4
|
||||||
|
OutputAudioMixerGroup: {fileID: 3533147658878909314, guid: 727a7e4b6df4b0d47897f7d8ee7fa323, type: 2}
|
||||||
|
m_audioClip: {fileID: 0}
|
||||||
|
m_Resource: {fileID: 8300000, guid: fca641cdc8dcd074483fad3db1cbe24c, type: 3}
|
||||||
|
m_PlayOnAwake: 1
|
||||||
|
m_Volume: 1
|
||||||
|
m_Pitch: 1
|
||||||
|
Loop: 0
|
||||||
|
Mute: 0
|
||||||
|
Spatialize: 0
|
||||||
|
SpatializePostEffects: 0
|
||||||
|
Priority: 128
|
||||||
|
DopplerLevel: 1
|
||||||
|
MinDistance: 1
|
||||||
|
MaxDistance: 500
|
||||||
|
Pan2D: 0
|
||||||
|
rolloffMode: 0
|
||||||
|
BypassEffects: 0
|
||||||
|
BypassListenerEffects: 0
|
||||||
|
BypassReverbZones: 0
|
||||||
|
rolloffCustomCurve:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Curve:
|
||||||
|
- serializedVersion: 3
|
||||||
|
time: 0
|
||||||
|
value: 1
|
||||||
|
inSlope: 0
|
||||||
|
outSlope: 0
|
||||||
|
tangentMode: 0
|
||||||
|
weightedMode: 0
|
||||||
|
inWeight: 0.33333334
|
||||||
|
outWeight: 0.33333334
|
||||||
|
- serializedVersion: 3
|
||||||
|
time: 1
|
||||||
|
value: 0
|
||||||
|
inSlope: 0
|
||||||
|
outSlope: 0
|
||||||
|
tangentMode: 0
|
||||||
|
weightedMode: 0
|
||||||
|
inWeight: 0.33333334
|
||||||
|
outWeight: 0.33333334
|
||||||
|
m_PreInfinity: 2
|
||||||
|
m_PostInfinity: 2
|
||||||
|
m_RotationOrder: 4
|
||||||
|
panLevelCustomCurve:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Curve:
|
||||||
|
- serializedVersion: 3
|
||||||
|
time: 0
|
||||||
|
value: 0
|
||||||
|
inSlope: 0
|
||||||
|
outSlope: 0
|
||||||
|
tangentMode: 0
|
||||||
|
weightedMode: 0
|
||||||
|
inWeight: 0.33333334
|
||||||
|
outWeight: 0.33333334
|
||||||
|
m_PreInfinity: 2
|
||||||
|
m_PostInfinity: 2
|
||||||
|
m_RotationOrder: 4
|
||||||
|
spreadCustomCurve:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Curve:
|
||||||
|
- serializedVersion: 3
|
||||||
|
time: 0
|
||||||
|
value: 0
|
||||||
|
inSlope: 0
|
||||||
|
outSlope: 0
|
||||||
|
tangentMode: 0
|
||||||
|
weightedMode: 0
|
||||||
|
inWeight: 0.33333334
|
||||||
|
outWeight: 0.33333334
|
||||||
|
m_PreInfinity: 2
|
||||||
|
m_PostInfinity: 2
|
||||||
|
m_RotationOrder: 4
|
||||||
|
reverbZoneMixCustomCurve:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Curve:
|
||||||
|
- serializedVersion: 3
|
||||||
|
time: 0
|
||||||
|
value: 1
|
||||||
|
inSlope: 0
|
||||||
|
outSlope: 0
|
||||||
|
tangentMode: 0
|
||||||
|
weightedMode: 0
|
||||||
|
inWeight: 0.33333334
|
||||||
|
outWeight: 0.33333334
|
||||||
|
m_PreInfinity: 2
|
||||||
|
m_PostInfinity: 2
|
||||||
|
m_RotationOrder: 4
|
||||||
--- !u!1 &1590200553513530823
|
--- !u!1 &1590200553513530823
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@@ -242,7 +371,7 @@ GameObject:
|
|||||||
m_Icon: {fileID: 0}
|
m_Icon: {fileID: 0}
|
||||||
m_NavMeshLayer: 0
|
m_NavMeshLayer: 0
|
||||||
m_StaticEditorFlags: 0
|
m_StaticEditorFlags: 0
|
||||||
m_IsActive: 1
|
m_IsActive: 0
|
||||||
--- !u!4 &1831065641766120066
|
--- !u!4 &1831065641766120066
|
||||||
Transform:
|
Transform:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@@ -263,7 +392,7 @@ Transform:
|
|||||||
- {fileID: 8442487091540635686}
|
- {fileID: 8442487091540635686}
|
||||||
- {fileID: 8879908034887781514}
|
- {fileID: 8879908034887781514}
|
||||||
- {fileID: 2211814522314670326}
|
- {fileID: 2211814522314670326}
|
||||||
m_Father: {fileID: 4592376486413311028}
|
m_Father: {fileID: 9007881587001685567}
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
--- !u!111 &1617577586792587006
|
--- !u!111 &1617577586792587006
|
||||||
Animation:
|
Animation:
|
||||||
@@ -312,7 +441,7 @@ GameObject:
|
|||||||
m_Icon: {fileID: 0}
|
m_Icon: {fileID: 0}
|
||||||
m_NavMeshLayer: 0
|
m_NavMeshLayer: 0
|
||||||
m_StaticEditorFlags: 0
|
m_StaticEditorFlags: 0
|
||||||
m_IsActive: 0
|
m_IsActive: 1
|
||||||
--- !u!4 &4249054603034392046
|
--- !u!4 &4249054603034392046
|
||||||
Transform:
|
Transform:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@@ -330,7 +459,7 @@ Transform:
|
|||||||
- {fileID: 3606233682966098341}
|
- {fileID: 3606233682966098341}
|
||||||
- {fileID: 9050619600904836405}
|
- {fileID: 9050619600904836405}
|
||||||
- {fileID: 4757850631734005462}
|
- {fileID: 4757850631734005462}
|
||||||
m_Father: {fileID: 4592376486413311028}
|
m_Father: {fileID: 9007881587001685567}
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
--- !u!111 &6215866005480392352
|
--- !u!111 &6215866005480392352
|
||||||
Animation:
|
Animation:
|
||||||
@@ -393,6 +522,7 @@ Transform:
|
|||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children:
|
m_Children:
|
||||||
- {fileID: 4592376486413311028}
|
- {fileID: 4592376486413311028}
|
||||||
|
- {fileID: 4893439260580271593}
|
||||||
m_Father: {fileID: 0}
|
m_Father: {fileID: 0}
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
--- !u!114 &4267886887244421663
|
--- !u!114 &4267886887244421663
|
||||||
@@ -407,8 +537,8 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 11500000, guid: c0f21d12fb6a50242b483dbdc3a6a1df, type: 3}
|
m_Script: {fileID: 11500000, guid: c0f21d12fb6a50242b483dbdc3a6a1df, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier: '::'
|
m_EditorClassIdentifier: '::'
|
||||||
divingGameManager: {fileID: 0}
|
playTutorial: 1
|
||||||
playTutorial: 0
|
tapPrompt: {fileID: 6751368003081662277}
|
||||||
--- !u!1 &3503751741805984614
|
--- !u!1 &3503751741805984614
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@@ -443,8 +573,8 @@ RectTransform:
|
|||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||||
m_AnchoredPosition: {x: 13.456177, y: -2.627655}
|
m_AnchoredPosition: {x: 22.853088, y: -89.07968}
|
||||||
m_SizeDelta: {x: 1204.5154, y: 802.1875}
|
m_SizeDelta: {x: 1185.7214, y: 975.0914}
|
||||||
m_Pivot: {x: 0.5, y: 0.5}
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
--- !u!222 &3845799704385814770
|
--- !u!222 &3845799704385814770
|
||||||
CanvasRenderer:
|
CanvasRenderer:
|
||||||
@@ -860,6 +990,43 @@ MonoBehaviour:
|
|||||||
m_FillOrigin: 0
|
m_FillOrigin: 0
|
||||||
m_UseSpriteMesh: 0
|
m_UseSpriteMesh: 0
|
||||||
m_PixelsPerUnitMultiplier: 1
|
m_PixelsPerUnitMultiplier: 1
|
||||||
|
--- !u!1 &5541992152058962912
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 9007881587001685567}
|
||||||
|
m_Layer: 5
|
||||||
|
m_Name: TutorialScreens
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &9007881587001685567
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 5541992152058962912}
|
||||||
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||||
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
|
m_ConstrainProportionsScale: 0
|
||||||
|
m_Children:
|
||||||
|
- {fileID: 4249054603034392046}
|
||||||
|
- {fileID: 1831065641766120066}
|
||||||
|
m_Father: {fileID: 4592376486413311028}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||||
|
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||||
|
m_AnchoredPosition: {x: 0, y: 0}
|
||||||
|
m_SizeDelta: {x: 100, y: 100}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
--- !u!1 &6118149484066388440
|
--- !u!1 &6118149484066388440
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@@ -894,8 +1061,8 @@ RectTransform:
|
|||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||||
m_AnchoredPosition: {x: 13.456177, y: -2.627655}
|
m_AnchoredPosition: {x: 22.853088, y: -89.07971}
|
||||||
m_SizeDelta: {x: 1204.5154, y: 802.1875}
|
m_SizeDelta: {x: 1185.721, y: 975.0914}
|
||||||
m_Pivot: {x: 0.5, y: 0.5}
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
--- !u!222 &4855560808002867609
|
--- !u!222 &4855560808002867609
|
||||||
CanvasRenderer:
|
CanvasRenderer:
|
||||||
@@ -1010,6 +1177,142 @@ MonoBehaviour:
|
|||||||
m_FillOrigin: 0
|
m_FillOrigin: 0
|
||||||
m_UseSpriteMesh: 0
|
m_UseSpriteMesh: 0
|
||||||
m_PixelsPerUnitMultiplier: 1
|
m_PixelsPerUnitMultiplier: 1
|
||||||
|
--- !u!1 &6751368003081662277
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 5554143010115146741}
|
||||||
|
- component: {fileID: 3254928157304415694}
|
||||||
|
- component: {fileID: 490204079952288596}
|
||||||
|
m_Layer: 5
|
||||||
|
m_Name: Text (TMP)
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &5554143010115146741
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6751368003081662277}
|
||||||
|
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||||
|
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||||
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
|
m_ConstrainProportionsScale: 0
|
||||||
|
m_Children: []
|
||||||
|
m_Father: {fileID: 4592376486413311028}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||||
|
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||||
|
m_AnchoredPosition: {x: 0.000015258789, y: -51.398}
|
||||||
|
m_SizeDelta: {x: 658.8605, y: 102.796875}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!222 &3254928157304415694
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6751368003081662277}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &490204079952288596
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6751368003081662277}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshProUGUI
|
||||||
|
m_Material: {fileID: 0}
|
||||||
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
m_RaycastTarget: 1
|
||||||
|
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
m_Maskable: 1
|
||||||
|
m_OnCullStateChanged:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_text: TAP TO SKIP
|
||||||
|
m_isRightToLeft: 0
|
||||||
|
m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
|
||||||
|
m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
|
||||||
|
m_fontSharedMaterials: []
|
||||||
|
m_fontMaterial: {fileID: 0}
|
||||||
|
m_fontMaterials: []
|
||||||
|
m_fontColor32:
|
||||||
|
serializedVersion: 2
|
||||||
|
rgba: 4294967295
|
||||||
|
m_fontColor: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
m_enableVertexGradient: 0
|
||||||
|
m_colorMode: 3
|
||||||
|
m_fontColorGradient:
|
||||||
|
topLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
topRight: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
bottomRight: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
m_fontColorGradientPreset: {fileID: 0}
|
||||||
|
m_spriteAsset: {fileID: 0}
|
||||||
|
m_tintAllSprites: 0
|
||||||
|
m_StyleSheet: {fileID: 0}
|
||||||
|
m_TextStyleHashCode: -1183493901
|
||||||
|
m_overrideHtmlColors: 0
|
||||||
|
m_faceColor:
|
||||||
|
serializedVersion: 2
|
||||||
|
rgba: 4294967295
|
||||||
|
m_fontSize: 75
|
||||||
|
m_fontSizeBase: 75
|
||||||
|
m_fontWeight: 400
|
||||||
|
m_enableAutoSizing: 0
|
||||||
|
m_fontSizeMin: 18
|
||||||
|
m_fontSizeMax: 72
|
||||||
|
m_fontStyle: 1
|
||||||
|
m_HorizontalAlignment: 2
|
||||||
|
m_VerticalAlignment: 512
|
||||||
|
m_textAlignment: 65535
|
||||||
|
m_characterSpacing: 0
|
||||||
|
m_wordSpacing: 0
|
||||||
|
m_lineSpacing: 0
|
||||||
|
m_lineSpacingMax: 0
|
||||||
|
m_paragraphSpacing: 0
|
||||||
|
m_charWidthMaxAdj: 0
|
||||||
|
m_TextWrappingMode: 1
|
||||||
|
m_wordWrappingRatios: 0.4
|
||||||
|
m_overflowMode: 0
|
||||||
|
m_linkedTextComponent: {fileID: 0}
|
||||||
|
parentLinkedComponent: {fileID: 0}
|
||||||
|
m_enableKerning: 0
|
||||||
|
m_ActiveFontFeatures: 6e72656b
|
||||||
|
m_enableExtraPadding: 0
|
||||||
|
checkPaddingRequired: 0
|
||||||
|
m_isRichText: 1
|
||||||
|
m_EmojiFallbackSupport: 1
|
||||||
|
m_parseCtrlCharacters: 1
|
||||||
|
m_isOrthographic: 1
|
||||||
|
m_isCullingEnabled: 0
|
||||||
|
m_horizontalMapping: 0
|
||||||
|
m_verticalMapping: 0
|
||||||
|
m_uvLineOffset: 0
|
||||||
|
m_geometrySortingOrder: 0
|
||||||
|
m_IsTextObjectScaleStatic: 0
|
||||||
|
m_VertexBufferAutoSizeReduction: 0
|
||||||
|
m_useMaxVisibleDescender: 1
|
||||||
|
m_pageToDisplay: 1
|
||||||
|
m_margin: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
m_isUsingLegacyAnimationComponent: 0
|
||||||
|
m_isVolumetricText: 0
|
||||||
|
m_hasFontAssetChanged: 0
|
||||||
|
m_baseMaterial: {fileID: 0}
|
||||||
|
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
|
||||||
--- !u!1 &7059429923783536925
|
--- !u!1 &7059429923783536925
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@@ -1043,8 +1346,8 @@ RectTransform:
|
|||||||
m_LocalScale: {x: 0, y: 0, z: 0}
|
m_LocalScale: {x: 0, y: 0, z: 0}
|
||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children:
|
m_Children:
|
||||||
- {fileID: 4249054603034392046}
|
- {fileID: 9007881587001685567}
|
||||||
- {fileID: 1831065641766120066}
|
- {fileID: 5554143010115146741}
|
||||||
m_Father: {fileID: 3183207532655435649}
|
m_Father: {fileID: 3183207532655435649}
|
||||||
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}
|
||||||
@@ -1070,7 +1373,7 @@ Canvas:
|
|||||||
m_OverridePixelPerfect: 0
|
m_OverridePixelPerfect: 0
|
||||||
m_SortingBucketNormalizedSize: 0
|
m_SortingBucketNormalizedSize: 0
|
||||||
m_VertexColorAlwaysGammaSpace: 0
|
m_VertexColorAlwaysGammaSpace: 0
|
||||||
m_AdditionalShaderChannelsFlag: 0
|
m_AdditionalShaderChannelsFlag: 25
|
||||||
m_UpdateRectTransformForStandalone: 0
|
m_UpdateRectTransformForStandalone: 0
|
||||||
m_SortingLayerID: 0
|
m_SortingLayerID: 0
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
|
|||||||
@@ -342,16 +342,16 @@ LineRenderer:
|
|||||||
m_SortingLayer: 0
|
m_SortingLayer: 0
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
m_Positions:
|
m_Positions:
|
||||||
- {x: -0.15602553, y: 4.0749445, z: 0}
|
- {x: -0.15602553, y: 4.074945, z: 0}
|
||||||
- {x: -0.1566351, y: 3.9736378, z: 0}
|
- {x: -0.1566351, y: 3.973638, z: 0}
|
||||||
- {x: -0.1572447, y: 3.8729858, z: 0}
|
- {x: -0.1572447, y: 3.8729856, z: 0}
|
||||||
- {x: -0.15785426, y: 3.7729874, z: 0}
|
- {x: -0.15785426, y: 3.7729874, z: 0}
|
||||||
- {x: -0.15846384, y: 3.6736438, z: 0}
|
- {x: -0.15846384, y: 3.6736436, z: 0}
|
||||||
- {x: -0.15907341, y: 3.5749545, z: 0}
|
- {x: -0.15907341, y: 3.574954, z: 0}
|
||||||
- {x: -0.15968299, y: 3.4769197, z: 0}
|
- {x: -0.15968299, y: 3.4769192, z: 0}
|
||||||
- {x: -0.16029257, y: 3.379539, z: 0}
|
- {x: -0.16029257, y: 3.3795385, z: 0}
|
||||||
- {x: -0.16090216, y: 3.2828128, z: 0}
|
- {x: -0.16090216, y: 3.2828126, z: 0}
|
||||||
- {x: -0.16151173, y: 3.186741, z: 0}
|
- {x: -0.16151173, y: 3.1867409, z: 0}
|
||||||
- {x: -0.16212131, y: 3.0913236, z: 0}
|
- {x: -0.16212131, y: 3.0913236, z: 0}
|
||||||
m_Parameters:
|
m_Parameters:
|
||||||
serializedVersion: 3
|
serializedVersion: 3
|
||||||
@@ -1149,7 +1149,7 @@ Transform:
|
|||||||
m_GameObject: {fileID: 747976396}
|
m_GameObject: {fileID: 747976396}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
m_LocalPosition: {x: 0, y: 3.1975174, z: 0}
|
m_LocalPosition: {x: 0, y: 3.197517, z: 0}
|
||||||
m_LocalScale: {x: 0.57574, y: 0.57574, z: 0.57574}
|
m_LocalScale: {x: 0.57574, y: 0.57574, z: 0.57574}
|
||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children:
|
m_Children:
|
||||||
@@ -1544,6 +1544,59 @@ Transform:
|
|||||||
m_Children: []
|
m_Children: []
|
||||||
m_Father: {fileID: 0}
|
m_Father: {fileID: 0}
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!1 &999630160 stripped
|
||||||
|
GameObject:
|
||||||
|
m_CorrespondingSourceObject: {fileID: 5541992152058962912, guid: a4dd78ff48942854ebb4c65025a8dc36, type: 3}
|
||||||
|
m_PrefabInstance: {fileID: 8347532583749285323}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
--- !u!114 &999630162
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 999630160}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 9e0b24e2f2ad54cc09940c320ed3cf4b, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier: PixelplacementAssembly::Pixelplacement.StateMachine
|
||||||
|
defaultState: {fileID: 1211973842}
|
||||||
|
currentState: {fileID: 0}
|
||||||
|
_unityEventsFolded: 0
|
||||||
|
verbose: 1
|
||||||
|
allowReentry: 0
|
||||||
|
returnToDefaultOnDisable: 1
|
||||||
|
OnStateExited:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
OnStateEntered:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
OnFirstStateEntered:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
OnFirstStateExited:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
OnLastStateEntered:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
OnLastStateExited:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
--- !u!114 &999630163
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 999630160}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 55938fb1577dd4ad3af7e994048c86f6, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier: PixelplacementAssembly::Pixelplacement.Initialization
|
||||||
--- !u!1 &1003335103
|
--- !u!1 &1003335103
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@@ -1701,7 +1754,7 @@ LineRenderer:
|
|||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
m_Positions:
|
m_Positions:
|
||||||
- {x: -0.15602553, y: 4.0749445, z: 0}
|
- {x: -0.15602553, y: 4.0749445, z: 0}
|
||||||
- {x: -0.11662118, y: 3.8796222, z: 0}
|
- {x: -0.11662118, y: 3.879622, z: 0}
|
||||||
- {x: -0.07721684, y: 3.7057445, z: 0}
|
- {x: -0.07721684, y: 3.7057445, z: 0}
|
||||||
- {x: -0.03781248, y: 3.5533106, z: 0}
|
- {x: -0.03781248, y: 3.5533106, z: 0}
|
||||||
- {x: 0.0015918687, y: 3.4223216, z: 0}
|
- {x: 0.0015918687, y: 3.4223216, z: 0}
|
||||||
@@ -1709,7 +1762,7 @@ LineRenderer:
|
|||||||
- {x: 0.08040057, y: 3.2246761, z: 0}
|
- {x: 0.08040057, y: 3.2246761, z: 0}
|
||||||
- {x: 0.11980491, y: 3.15802, z: 0}
|
- {x: 0.11980491, y: 3.15802, z: 0}
|
||||||
- {x: 0.15920927, y: 3.1128082, z: 0}
|
- {x: 0.15920927, y: 3.1128082, z: 0}
|
||||||
- {x: 0.1986136, y: 3.0890408, z: 0}
|
- {x: 0.1986136, y: 3.0890405, z: 0}
|
||||||
- {x: 0.23801796, y: 3.0867176, z: 0}
|
- {x: 0.23801796, y: 3.0867176, z: 0}
|
||||||
m_Parameters:
|
m_Parameters:
|
||||||
serializedVersion: 3
|
serializedVersion: 3
|
||||||
@@ -1971,6 +2024,51 @@ MonoBehaviour:
|
|||||||
m_VarianceClampScale: 0.9
|
m_VarianceClampScale: 0.9
|
||||||
m_ContrastAdaptiveSharpening: 0
|
m_ContrastAdaptiveSharpening: 0
|
||||||
m_Version: 2
|
m_Version: 2
|
||||||
|
--- !u!1 &1173818904 stripped
|
||||||
|
GameObject:
|
||||||
|
m_CorrespondingSourceObject: {fileID: 6751368003081662277, guid: a4dd78ff48942854ebb4c65025a8dc36, type: 3}
|
||||||
|
m_PrefabInstance: {fileID: 8347532583749285323}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
--- !u!114 &1173818908
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1173818904}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: b75de64fb2fd4ff0b869bf469e2becea, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier: AppleHillsScripts::UI.BlinkingCanvasGroup
|
||||||
|
minAlpha: 0
|
||||||
|
maxAlpha: 1
|
||||||
|
legDuration: 0.5
|
||||||
|
startDelay: 0
|
||||||
|
obeyTimescale: 0
|
||||||
|
easeCurve:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Curve: []
|
||||||
|
m_PreInfinity: 2
|
||||||
|
m_PostInfinity: 2
|
||||||
|
m_RotationOrder: 4
|
||||||
|
--- !u!225 &1173818909
|
||||||
|
CanvasGroup:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1173818904}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_Alpha: 1
|
||||||
|
m_Interactable: 1
|
||||||
|
m_BlocksRaycasts: 1
|
||||||
|
m_IgnoreParentGroups: 0
|
||||||
|
--- !u!1 &1211973842 stripped
|
||||||
|
GameObject:
|
||||||
|
m_CorrespondingSourceObject: {fileID: 2271162218602898139, guid: a4dd78ff48942854ebb4c65025a8dc36, type: 3}
|
||||||
|
m_PrefabInstance: {fileID: 8347532583749285323}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
--- !u!1 &1224833348
|
--- !u!1 &1224833348
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@@ -2138,135 +2236,6 @@ Transform:
|
|||||||
m_Children: []
|
m_Children: []
|
||||||
m_Father: {fileID: 2106431002}
|
m_Father: {fileID: 2106431002}
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
--- !u!1 &1363116017
|
|
||||||
GameObject:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
serializedVersion: 6
|
|
||||||
m_Component:
|
|
||||||
- component: {fileID: 1363116018}
|
|
||||||
- component: {fileID: 1363116019}
|
|
||||||
m_Layer: 0
|
|
||||||
m_Name: TutorialAudio
|
|
||||||
m_TagString: Untagged
|
|
||||||
m_Icon: {fileID: 0}
|
|
||||||
m_NavMeshLayer: 0
|
|
||||||
m_StaticEditorFlags: 0
|
|
||||||
m_IsActive: 1
|
|
||||||
--- !u!4 &1363116018
|
|
||||||
Transform:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 1363116017}
|
|
||||||
serializedVersion: 2
|
|
||||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
|
||||||
m_LocalPosition: {x: -80.867836, y: 74.80073, z: 0}
|
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
|
||||||
m_ConstrainProportionsScale: 0
|
|
||||||
m_Children: []
|
|
||||||
m_Father: {fileID: 1849171394}
|
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
|
||||||
--- !u!82 &1363116019
|
|
||||||
AudioSource:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 1363116017}
|
|
||||||
m_Enabled: 1
|
|
||||||
serializedVersion: 4
|
|
||||||
OutputAudioMixerGroup: {fileID: 3533147658878909314, guid: 727a7e4b6df4b0d47897f7d8ee7fa323, type: 2}
|
|
||||||
m_audioClip: {fileID: 0}
|
|
||||||
m_Resource: {fileID: 8300000, guid: fca641cdc8dcd074483fad3db1cbe24c, type: 3}
|
|
||||||
m_PlayOnAwake: 1
|
|
||||||
m_Volume: 1
|
|
||||||
m_Pitch: 1
|
|
||||||
Loop: 0
|
|
||||||
Mute: 0
|
|
||||||
Spatialize: 0
|
|
||||||
SpatializePostEffects: 0
|
|
||||||
Priority: 128
|
|
||||||
DopplerLevel: 1
|
|
||||||
MinDistance: 1
|
|
||||||
MaxDistance: 500
|
|
||||||
Pan2D: 0
|
|
||||||
rolloffMode: 0
|
|
||||||
BypassEffects: 0
|
|
||||||
BypassListenerEffects: 0
|
|
||||||
BypassReverbZones: 0
|
|
||||||
rolloffCustomCurve:
|
|
||||||
serializedVersion: 2
|
|
||||||
m_Curve:
|
|
||||||
- serializedVersion: 3
|
|
||||||
time: 0
|
|
||||||
value: 1
|
|
||||||
inSlope: 0
|
|
||||||
outSlope: 0
|
|
||||||
tangentMode: 0
|
|
||||||
weightedMode: 0
|
|
||||||
inWeight: 0.33333334
|
|
||||||
outWeight: 0.33333334
|
|
||||||
- serializedVersion: 3
|
|
||||||
time: 1
|
|
||||||
value: 0
|
|
||||||
inSlope: 0
|
|
||||||
outSlope: 0
|
|
||||||
tangentMode: 0
|
|
||||||
weightedMode: 0
|
|
||||||
inWeight: 0.33333334
|
|
||||||
outWeight: 0.33333334
|
|
||||||
m_PreInfinity: 2
|
|
||||||
m_PostInfinity: 2
|
|
||||||
m_RotationOrder: 4
|
|
||||||
panLevelCustomCurve:
|
|
||||||
serializedVersion: 2
|
|
||||||
m_Curve:
|
|
||||||
- serializedVersion: 3
|
|
||||||
time: 0
|
|
||||||
value: 0
|
|
||||||
inSlope: 0
|
|
||||||
outSlope: 0
|
|
||||||
tangentMode: 0
|
|
||||||
weightedMode: 0
|
|
||||||
inWeight: 0.33333334
|
|
||||||
outWeight: 0.33333334
|
|
||||||
m_PreInfinity: 2
|
|
||||||
m_PostInfinity: 2
|
|
||||||
m_RotationOrder: 4
|
|
||||||
spreadCustomCurve:
|
|
||||||
serializedVersion: 2
|
|
||||||
m_Curve:
|
|
||||||
- serializedVersion: 3
|
|
||||||
time: 0
|
|
||||||
value: 0
|
|
||||||
inSlope: 0
|
|
||||||
outSlope: 0
|
|
||||||
tangentMode: 0
|
|
||||||
weightedMode: 0
|
|
||||||
inWeight: 0.33333334
|
|
||||||
outWeight: 0.33333334
|
|
||||||
m_PreInfinity: 2
|
|
||||||
m_PostInfinity: 2
|
|
||||||
m_RotationOrder: 4
|
|
||||||
reverbZoneMixCustomCurve:
|
|
||||||
serializedVersion: 2
|
|
||||||
m_Curve:
|
|
||||||
- serializedVersion: 3
|
|
||||||
time: 0
|
|
||||||
value: 1
|
|
||||||
inSlope: 0
|
|
||||||
outSlope: 0
|
|
||||||
tangentMode: 0
|
|
||||||
weightedMode: 0
|
|
||||||
inWeight: 0.33333334
|
|
||||||
outWeight: 0.33333334
|
|
||||||
m_PreInfinity: 2
|
|
||||||
m_PostInfinity: 2
|
|
||||||
m_RotationOrder: 4
|
|
||||||
--- !u!1 &1376741227
|
--- !u!1 &1376741227
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@@ -2549,10 +2518,10 @@ LineRenderer:
|
|||||||
m_SortingLayer: 0
|
m_SortingLayer: 0
|
||||||
m_SortingOrder: 0
|
m_SortingOrder: 0
|
||||||
m_Positions:
|
m_Positions:
|
||||||
- {x: -0.15602553, y: 4.074945, z: 0}
|
- {x: -0.15602553, y: 4.0749445, z: 0}
|
||||||
- {x: -0.18956745, y: 3.8764977, z: 0}
|
- {x: -0.18956745, y: 3.8764973, z: 0}
|
||||||
- {x: -0.22310936, y: 3.7000234, z: 0}
|
- {x: -0.22310936, y: 3.7000232, z: 0}
|
||||||
- {x: -0.25665125, y: 3.5455208, z: 0}
|
- {x: -0.25665125, y: 3.5455203, z: 0}
|
||||||
- {x: -0.29019317, y: 3.412991, z: 0}
|
- {x: -0.29019317, y: 3.412991, z: 0}
|
||||||
- {x: -0.32373506, y: 3.3024335, z: 0}
|
- {x: -0.32373506, y: 3.3024335, z: 0}
|
||||||
- {x: -0.35727698, y: 3.2138484, z: 0}
|
- {x: -0.35727698, y: 3.2138484, z: 0}
|
||||||
@@ -2926,11 +2895,6 @@ SpriteRenderer:
|
|||||||
m_WasSpriteAssigned: 1
|
m_WasSpriteAssigned: 1
|
||||||
m_MaskInteraction: 0
|
m_MaskInteraction: 0
|
||||||
m_SpriteSortPoint: 0
|
m_SpriteSortPoint: 0
|
||||||
--- !u!4 &1849171394 stripped
|
|
||||||
Transform:
|
|
||||||
m_CorrespondingSourceObject: {fileID: 3183207532655435649, guid: a4dd78ff48942854ebb4c65025a8dc36, type: 3}
|
|
||||||
m_PrefabInstance: {fileID: 8347532583749285323}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
--- !u!1 &1916796529
|
--- !u!1 &1916796529
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@@ -3440,25 +3404,24 @@ PrefabInstance:
|
|||||||
propertyPath: m_Name
|
propertyPath: m_Name
|
||||||
value: Tutorial
|
value: Tutorial
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 3332446944854334578, guid: a4dd78ff48942854ebb4c65025a8dc36, type: 3}
|
m_RemovedComponents:
|
||||||
propertyPath: m_IsActive
|
- {fileID: 8086909437439386099, guid: a4dd78ff48942854ebb4c65025a8dc36, type: 3}
|
||||||
value: 1
|
- {fileID: 2002496630232568573, guid: a4dd78ff48942854ebb4c65025a8dc36, type: 3}
|
||||||
objectReference: {fileID: 0}
|
|
||||||
- target: {fileID: 4267886887244421663, guid: a4dd78ff48942854ebb4c65025a8dc36, type: 3}
|
|
||||||
propertyPath: playTutorial
|
|
||||||
value: 1
|
|
||||||
objectReference: {fileID: 0}
|
|
||||||
- target: {fileID: 4267886887244421663, guid: a4dd78ff48942854ebb4c65025a8dc36, type: 3}
|
|
||||||
propertyPath: divingGameManager
|
|
||||||
value:
|
|
||||||
objectReference: {fileID: 424805725}
|
|
||||||
m_RemovedComponents: []
|
|
||||||
m_RemovedGameObjects: []
|
m_RemovedGameObjects: []
|
||||||
m_AddedGameObjects:
|
m_AddedGameObjects: []
|
||||||
- targetCorrespondingSourceObject: {fileID: 3183207532655435649, guid: a4dd78ff48942854ebb4c65025a8dc36, type: 3}
|
m_AddedComponents:
|
||||||
|
- targetCorrespondingSourceObject: {fileID: 5541992152058962912, guid: a4dd78ff48942854ebb4c65025a8dc36, type: 3}
|
||||||
insertIndex: -1
|
insertIndex: -1
|
||||||
addedObject: {fileID: 1363116018}
|
addedObject: {fileID: 999630163}
|
||||||
m_AddedComponents: []
|
- targetCorrespondingSourceObject: {fileID: 5541992152058962912, guid: a4dd78ff48942854ebb4c65025a8dc36, type: 3}
|
||||||
|
insertIndex: -1
|
||||||
|
addedObject: {fileID: 999630162}
|
||||||
|
- targetCorrespondingSourceObject: {fileID: 6751368003081662277, guid: a4dd78ff48942854ebb4c65025a8dc36, type: 3}
|
||||||
|
insertIndex: -1
|
||||||
|
addedObject: {fileID: 1173818909}
|
||||||
|
- targetCorrespondingSourceObject: {fileID: 6751368003081662277, guid: a4dd78ff48942854ebb4c65025a8dc36, type: 3}
|
||||||
|
insertIndex: -1
|
||||||
|
addedObject: {fileID: 1173818908}
|
||||||
m_SourcePrefab: {fileID: 100100000, guid: a4dd78ff48942854ebb4c65025a8dc36, type: 3}
|
m_SourcePrefab: {fileID: 100100000, guid: a4dd78ff48942854ebb4c65025a8dc36, type: 3}
|
||||||
--- !u!1660057539 &9223372036854775807
|
--- !u!1660057539 &9223372036854775807
|
||||||
SceneRoots:
|
SceneRoots:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Bootstrap;
|
using Bootstrap;
|
||||||
using Core;
|
using Core;
|
||||||
@@ -7,7 +6,6 @@ using UnityEngine;
|
|||||||
using UnityEngine.AddressableAssets;
|
using UnityEngine.AddressableAssets;
|
||||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||||
using UnityEngine.Playables;
|
using UnityEngine.Playables;
|
||||||
using UnityEngine.SceneManagement;
|
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using UI.Core;
|
using UI.Core;
|
||||||
|
|
||||||
|
|||||||
@@ -1,38 +1,28 @@
|
|||||||
using UnityEngine;
|
using System;
|
||||||
using AppleHills.Core.Settings;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using AppleHills.Core.Interfaces;
|
using AppleHills.Core.Interfaces;
|
||||||
using Core;
|
using AppleHills.Core.Settings;
|
||||||
using UI;
|
|
||||||
using Bootstrap;
|
using Bootstrap;
|
||||||
|
using Input;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
/// <summary>
|
namespace Core
|
||||||
/// Singleton manager for global game state and settings. Provides accessors for various gameplay parameters.
|
|
||||||
/// </summary>
|
|
||||||
public class GameManager : MonoBehaviour
|
|
||||||
{
|
{
|
||||||
private static GameManager _instance;
|
|
||||||
private static bool _isQuitting = false;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Singleton instance of the GameManager. No longer creates an instance if one doesn't exist.
|
/// Singleton manager for global game state and settings. Provides accessors for various gameplay parameters.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
public class GameManager : MonoBehaviour
|
||||||
|
{
|
||||||
|
// Singleton implementation
|
||||||
|
private static GameManager _instance;
|
||||||
public static GameManager Instance => _instance;
|
public static GameManager Instance => _instance;
|
||||||
|
|
||||||
[Header("Settings Status")]
|
private bool _settingsLoaded;
|
||||||
[SerializeField] private bool _settingsLoaded = false;
|
private bool _developerSettingsLoaded;
|
||||||
[SerializeField] private bool _developerSettingsLoaded = false;
|
|
||||||
public bool SettingsLoaded => _settingsLoaded;
|
|
||||||
public bool DeveloperSettingsLoaded => _developerSettingsLoaded;
|
|
||||||
|
|
||||||
[Header("Game State")]
|
// Pausable implementation (counter-based)
|
||||||
[SerializeField] private bool _isPaused = false;
|
private int _pauseCount;
|
||||||
|
public bool IsPaused => _pauseCount > 0;
|
||||||
/// <summary>
|
|
||||||
/// Current pause state of the game
|
|
||||||
/// </summary>
|
|
||||||
public bool IsPaused => _isPaused;
|
|
||||||
|
|
||||||
// List of pausable components that have registered with the GameManager
|
// List of pausable components that have registered with the GameManager
|
||||||
private List<IPausable> _pausableComponents = new List<IPausable>();
|
private List<IPausable> _pausableComponents = new List<IPausable>();
|
||||||
@@ -45,10 +35,8 @@ public class GameManager : MonoBehaviour
|
|||||||
{
|
{
|
||||||
_instance = this;
|
_instance = this;
|
||||||
|
|
||||||
// Create settings provider if it doesn't exist
|
// Create settings providers if it doesn't exist
|
||||||
SettingsProvider.Instance.gameObject.name = "Settings Provider";
|
SettingsProvider.Instance.gameObject.name = "Settings Provider";
|
||||||
|
|
||||||
// Create developer settings provider if it doesn't exist
|
|
||||||
DeveloperSettingsProvider.Instance.gameObject.name = "Developer Settings Provider";
|
DeveloperSettingsProvider.Instance.gameObject.name = "Developer Settings Provider";
|
||||||
|
|
||||||
// Load all settings synchronously during Awake
|
// Load all settings synchronously during Awake
|
||||||
@@ -63,30 +51,7 @@ public class GameManager : MonoBehaviour
|
|||||||
|
|
||||||
private void InitializePostBoot()
|
private void InitializePostBoot()
|
||||||
{
|
{
|
||||||
// Find and subscribe to PauseMenu events
|
// For post-boot correct initialization order
|
||||||
PauseMenu pauseMenu = PauseMenu.Instance;
|
|
||||||
if (pauseMenu != null)
|
|
||||||
{
|
|
||||||
pauseMenu.OnGamePaused += OnPauseMenuPaused;
|
|
||||||
pauseMenu.OnGameResumed += OnPauseMenuResumed;
|
|
||||||
|
|
||||||
Logging.Debug("[GameManager] Subscribed to PauseMenu events");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Logging.Warning("[GameManager] PauseMenu not found. Pause functionality won't work properly.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnDestroy()
|
|
||||||
{
|
|
||||||
// Unsubscribe from PauseMenu events
|
|
||||||
PauseMenu pauseMenu = FindFirstObjectByType<PauseMenu>();
|
|
||||||
if (pauseMenu != null)
|
|
||||||
{
|
|
||||||
pauseMenu.OnGamePaused -= OnPauseMenuPaused;
|
|
||||||
pauseMenu.OnGameResumed -= OnPauseMenuResumed;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -100,7 +65,7 @@ public class GameManager : MonoBehaviour
|
|||||||
_pausableComponents.Add(component);
|
_pausableComponents.Add(component);
|
||||||
|
|
||||||
// If the game is already paused, pause the component immediately
|
// If the game is already paused, pause the component immediately
|
||||||
if (_isPaused)
|
if (IsPaused)
|
||||||
{
|
{
|
||||||
component.Pause();
|
component.Pause();
|
||||||
}
|
}
|
||||||
@@ -123,72 +88,68 @@ public class GameManager : MonoBehaviour
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when the PauseMenu broadcasts a pause event
|
/// Request a pause. Multiple systems can request pause; the game only resumes when all requests are released.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void OnPauseMenuPaused()
|
/// <param name="requester">Optional object requesting the pause (for logging)</param>
|
||||||
|
public void RequestPause(object requester = null)
|
||||||
{
|
{
|
||||||
PauseGame();
|
_pauseCount++;
|
||||||
|
if (_pauseCount == 1)
|
||||||
|
{
|
||||||
|
ApplyPause(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
Logging.Debug($"[GameManager] Pause requested by {requester?.ToString() ?? "Unknown"}. pauseCount = {_pauseCount}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when the PauseMenu broadcasts a resume event
|
/// Release a previously requested pause. If this brings the pause count to zero the game resumes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void OnPauseMenuResumed()
|
/// <param name="requester">Optional object releasing the pause (for logging)</param>
|
||||||
|
public void ReleasePause(object requester = null)
|
||||||
{
|
{
|
||||||
ResumeGame();
|
_pauseCount = Mathf.Max(0, _pauseCount - 1);
|
||||||
|
if (_pauseCount == 0)
|
||||||
|
{
|
||||||
|
ApplyPause(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Logging.Debug($"[GameManager] Pause released by {requester?.ToString() ?? "Unknown"}. pauseCount = {_pauseCount}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Pause the game and notify all registered pausable components
|
/// Apply pause/resume state to registered components and global systems.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void PauseGame()
|
/// <param name="shouldPause">True to pause; false to resume</param>
|
||||||
|
private void ApplyPause(bool shouldPause)
|
||||||
{
|
{
|
||||||
if (_isPaused) return; // Already paused
|
// TODO: Do we want to stop time?
|
||||||
|
// Time.timeScale = shouldPause ? 0f : 1f;
|
||||||
|
|
||||||
_isPaused = true;
|
// Notify registered components
|
||||||
|
|
||||||
// Pause all registered components
|
|
||||||
foreach (var component in _pausableComponents)
|
foreach (var component in _pausableComponents)
|
||||||
{
|
{
|
||||||
|
if (shouldPause)
|
||||||
component.Pause();
|
component.Pause();
|
||||||
}
|
else
|
||||||
|
|
||||||
// Broadcast pause event
|
|
||||||
OnGamePaused?.Invoke();
|
|
||||||
|
|
||||||
Logging.Debug($"[GameManager] Game paused. Paused {_pausableComponents.Count} components.");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Resume the game and notify all registered pausable components
|
|
||||||
/// </summary>
|
|
||||||
public void ResumeGame()
|
|
||||||
{
|
|
||||||
if (!_isPaused) return; // Already running
|
|
||||||
|
|
||||||
_isPaused = false;
|
|
||||||
|
|
||||||
// Resume all registered components
|
|
||||||
foreach (var component in _pausableComponents)
|
|
||||||
{
|
|
||||||
component.DoResume();
|
component.DoResume();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Broadcast resume event
|
// Fire events
|
||||||
|
if (shouldPause)
|
||||||
|
{
|
||||||
|
// TODO: Stop input here?
|
||||||
|
InputManager.Instance.SetInputMode(InputMode.UI);
|
||||||
|
OnGamePaused?.Invoke();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: Release input here?
|
||||||
|
InputManager.Instance.SetInputMode(InputMode.GameAndUI);
|
||||||
OnGameResumed?.Invoke();
|
OnGameResumed?.Invoke();
|
||||||
|
|
||||||
Logging.Debug($"[GameManager] Game resumed. Resumed {_pausableComponents.Count} components.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
Logging.Debug($"[GameManager] Game {(shouldPause ? "paused" : "resumed")}. Paused {_pausableComponents.Count} components.");
|
||||||
/// Toggle the pause state of the game
|
|
||||||
/// </summary>
|
|
||||||
public void TogglePause()
|
|
||||||
{
|
|
||||||
if (_isPaused)
|
|
||||||
ResumeGame();
|
|
||||||
else
|
|
||||||
PauseGame();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeSettings()
|
private void InitializeSettings()
|
||||||
@@ -265,11 +226,6 @@ public class GameManager : MonoBehaviour
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnApplicationQuit()
|
|
||||||
{
|
|
||||||
_isQuitting = true;
|
|
||||||
ServiceLocator.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper method to get settings
|
// Helper method to get settings
|
||||||
private T GetSettings<T>() where T : class
|
private T GetSettings<T>() where T : class
|
||||||
@@ -301,4 +257,5 @@ public class GameManager : MonoBehaviour
|
|||||||
public float PlayerStopDistance => GetSettings<IInteractionSettings>()?.PlayerStopDistance ?? 6.0f;
|
public float PlayerStopDistance => GetSettings<IInteractionSettings>()?.PlayerStopDistance ?? 6.0f;
|
||||||
public float PlayerStopDistanceDirectInteraction => GetSettings<IInteractionSettings>()?.PlayerStopDistanceDirectInteraction ?? 2.0f;
|
public float PlayerStopDistanceDirectInteraction => GetSettings<IInteractionSettings>()?.PlayerStopDistanceDirectInteraction ?? 2.0f;
|
||||||
public float DefaultPuzzlePromptRange => GetSettings<IInteractionSettings>()?.DefaultPuzzlePromptRange ?? 3.0f;
|
public float DefaultPuzzlePromptRange => GetSettings<IInteractionSettings>()?.DefaultPuzzlePromptRange ?? 3.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,5 @@ namespace AppleHills.Core.Interfaces
|
|||||||
/// Resumes the component's functionality
|
/// Resumes the component's functionality
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void DoResume();
|
void DoResume();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets whether the component is currently paused
|
|
||||||
/// </summary>
|
|
||||||
bool IsPaused { get; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using UnityEngine;
|
using Core;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace AppleHills
|
namespace AppleHills
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -29,12 +29,6 @@ namespace Minigames.DivingForPictures
|
|||||||
private Coroutine _wobbleCoroutine;
|
private Coroutine _wobbleCoroutine;
|
||||||
private Coroutine _offScreenCheckCoroutine;
|
private Coroutine _offScreenCheckCoroutine;
|
||||||
|
|
||||||
// Pause state tracking
|
|
||||||
private bool _isPaused = false;
|
|
||||||
|
|
||||||
// IPausable implementation
|
|
||||||
public bool IsPaused => _isPaused;
|
|
||||||
|
|
||||||
void Awake()
|
void Awake()
|
||||||
{
|
{
|
||||||
// Cache references and randomize time offset for wobble
|
// Cache references and randomize time offset for wobble
|
||||||
@@ -67,9 +61,6 @@ namespace Minigames.DivingForPictures
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Pause()
|
public void Pause()
|
||||||
{
|
{
|
||||||
if (_isPaused) return; // Already paused
|
|
||||||
|
|
||||||
_isPaused = true;
|
|
||||||
StopBubbleBehavior();
|
StopBubbleBehavior();
|
||||||
|
|
||||||
// Debug log for troubleshooting
|
// Debug log for troubleshooting
|
||||||
@@ -81,9 +72,6 @@ namespace Minigames.DivingForPictures
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void DoResume()
|
public void DoResume()
|
||||||
{
|
{
|
||||||
if (!_isPaused) return; // Already running
|
|
||||||
|
|
||||||
_isPaused = false;
|
|
||||||
StartBubbleBehavior();
|
StartBubbleBehavior();
|
||||||
|
|
||||||
// Debug log for troubleshooting
|
// Debug log for troubleshooting
|
||||||
@@ -95,7 +83,7 @@ namespace Minigames.DivingForPictures
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void StartBubbleBehavior()
|
private void StartBubbleBehavior()
|
||||||
{
|
{
|
||||||
if (_isPaused || !isActiveAndEnabled) return; // Don't start if paused
|
if (GameManager.Instance.IsPaused || !isActiveAndEnabled) return; // Don't start if paused
|
||||||
|
|
||||||
_movementCoroutine = StartCoroutine(MovementCoroutine());
|
_movementCoroutine = StartCoroutine(MovementCoroutine());
|
||||||
_wobbleCoroutine = StartCoroutine(WobbleCoroutine());
|
_wobbleCoroutine = StartCoroutine(WobbleCoroutine());
|
||||||
|
|||||||
@@ -25,15 +25,9 @@ namespace Minigames.DivingForPictures
|
|||||||
private UnityEngine.Camera _mainCamera; // Cache camera reference
|
private UnityEngine.Camera _mainCamera; // Cache camera reference
|
||||||
private bool _isSurfacing = false;
|
private bool _isSurfacing = false;
|
||||||
|
|
||||||
// Pause state
|
|
||||||
private bool _isPaused = false;
|
|
||||||
|
|
||||||
// Coroutines for pause/resume
|
// Coroutines for pause/resume
|
||||||
private Coroutine _spawnCoroutine;
|
private Coroutine _spawnCoroutine;
|
||||||
|
|
||||||
// IPausable implementation
|
|
||||||
public bool IsPaused => _isPaused;
|
|
||||||
|
|
||||||
void Awake()
|
void Awake()
|
||||||
{
|
{
|
||||||
_mainCamera = UnityEngine.Camera.main;
|
_mainCamera = UnityEngine.Camera.main;
|
||||||
@@ -87,10 +81,6 @@ namespace Minigames.DivingForPictures
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Pause()
|
public void Pause()
|
||||||
{
|
{
|
||||||
if (_isPaused) return; // Already paused
|
|
||||||
|
|
||||||
_isPaused = true;
|
|
||||||
|
|
||||||
// Stop spawning coroutine
|
// Stop spawning coroutine
|
||||||
if (_spawnCoroutine != null)
|
if (_spawnCoroutine != null)
|
||||||
{
|
{
|
||||||
@@ -116,10 +106,6 @@ namespace Minigames.DivingForPictures
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void DoResume()
|
public void DoResume()
|
||||||
{
|
{
|
||||||
if (!_isPaused) return; // Already running
|
|
||||||
|
|
||||||
_isPaused = false;
|
|
||||||
|
|
||||||
// Restart spawning coroutine
|
// Restart spawning coroutine
|
||||||
StartSpawningCoroutine();
|
StartSpawningCoroutine();
|
||||||
|
|
||||||
@@ -141,7 +127,7 @@ namespace Minigames.DivingForPictures
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void StartSpawningCoroutine()
|
private void StartSpawningCoroutine()
|
||||||
{
|
{
|
||||||
if (_spawnCoroutine == null && !_isPaused)
|
if (_spawnCoroutine == null && !GameManager.Instance.IsPaused)
|
||||||
{
|
{
|
||||||
_spawnCoroutine = StartCoroutine(SpawnBubblesRoutine());
|
_spawnCoroutine = StartCoroutine(SpawnBubblesRoutine());
|
||||||
}
|
}
|
||||||
@@ -219,7 +205,7 @@ namespace Minigames.DivingForPictures
|
|||||||
bubble.SetWobbleScaleLimits(_devSettings.BubbleWobbleMinScale, _devSettings.BubbleWobbleMaxScale);
|
bubble.SetWobbleScaleLimits(_devSettings.BubbleWobbleMinScale, _devSettings.BubbleWobbleMaxScale);
|
||||||
|
|
||||||
// If the game is already paused, pause this bubble immediately
|
// If the game is already paused, pause this bubble immediately
|
||||||
if (_isPaused)
|
if (GameManager.Instance.IsPaused)
|
||||||
{
|
{
|
||||||
bubble.Pause();
|
bubble.Pause();
|
||||||
}
|
}
|
||||||
@@ -262,7 +248,7 @@ namespace Minigames.DivingForPictures
|
|||||||
{
|
{
|
||||||
Logging.Debug("[BubbleSpawner] Started bubble spawning coroutine");
|
Logging.Debug("[BubbleSpawner] Started bubble spawning coroutine");
|
||||||
|
|
||||||
while (enabled && gameObject.activeInHierarchy && !_isPaused)
|
while (enabled && gameObject.activeInHierarchy && !GameManager.Instance.IsPaused)
|
||||||
{
|
{
|
||||||
SpawnBubble();
|
SpawnBubble();
|
||||||
SetNextSpawnInterval(); // Set interval for next spawn
|
SetNextSpawnInterval(); // Set interval for next spawn
|
||||||
|
|||||||
@@ -7,8 +7,9 @@ using Minigames.DivingForPictures.PictureCamera;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using Bootstrap;
|
||||||
using UI;
|
using UI;
|
||||||
|
using UI.Core;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Events;
|
using UnityEngine.Events;
|
||||||
using UnityEngine.Playables;
|
using UnityEngine.Playables;
|
||||||
@@ -38,24 +39,24 @@ namespace Minigames.DivingForPictures
|
|||||||
public CameraViewfinderManager viewfinderManager;
|
public CameraViewfinderManager viewfinderManager;
|
||||||
|
|
||||||
// Settings reference
|
// Settings reference
|
||||||
private IDivingMinigameSettings settings;
|
private IDivingMinigameSettings _settings;
|
||||||
|
|
||||||
// Private state variables
|
// Private state variables
|
||||||
private int playerScore = 0;
|
private int _playerScore = 0;
|
||||||
private float currentSpawnProbability;
|
private float _currentSpawnProbability;
|
||||||
private float lastSpawnTime = -100f;
|
private float _lastSpawnTime = -100f;
|
||||||
private float timeSinceLastSpawn = 0f;
|
private float _timeSinceLastSpawn = 0f;
|
||||||
private List<Monster> activeMonsters = new List<Monster>();
|
private List<Monster> _activeMonsters = new List<Monster>();
|
||||||
|
|
||||||
// Velocity management
|
// Velocity management
|
||||||
// Velocity state tracking
|
// Velocity state tracking
|
||||||
private float currentVelocityFactor = 1.0f; // 1.0 = normal descent speed, -1.0 * surfacingSpeedFactor = full surfacing speed
|
private float _currentVelocityFactor = 1.0f; // 1.0 = normal descent speed, -1.0 * surfacingSpeedFactor = full surfacing speed
|
||||||
private Coroutine velocityTransitionCoroutine;
|
private Coroutine _velocityTransitionCoroutine;
|
||||||
private Coroutine surfacingSequenceCoroutine;
|
private Coroutine _surfacingSequenceCoroutine;
|
||||||
|
|
||||||
// Public properties
|
// Public properties
|
||||||
public int PlayerScore => playerScore;
|
public int PlayerScore => _playerScore;
|
||||||
public float CurrentVelocityFactor => currentVelocityFactor;
|
public float CurrentVelocityFactor => _currentVelocityFactor;
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
public event Action<int> OnScoreChanged;
|
public event Action<int> OnScoreChanged;
|
||||||
@@ -67,8 +68,8 @@ namespace Minigames.DivingForPictures
|
|||||||
public event Action<float> OnVelocityFactorChanged;
|
public event Action<float> OnVelocityFactorChanged;
|
||||||
|
|
||||||
// Private state variables for rope system
|
// Private state variables for rope system
|
||||||
private int currentRopeIndex = 0;
|
private int _currentRopeIndex = 0;
|
||||||
private bool isGameOver = false;
|
private bool _isGameOver = false;
|
||||||
private bool _isSurfacing = false;
|
private bool _isSurfacing = false;
|
||||||
|
|
||||||
// Initialization state
|
// Initialization state
|
||||||
@@ -77,23 +78,17 @@ namespace Minigames.DivingForPictures
|
|||||||
// Used to track if we're currently surfacing
|
// Used to track if we're currently surfacing
|
||||||
public bool IsSurfacing => _isSurfacing;
|
public bool IsSurfacing => _isSurfacing;
|
||||||
|
|
||||||
// Event for game components to subscribe to
|
// TODO: Get rid of this in favor of proper game pausing?
|
||||||
public event Action OnGameInitialized;
|
public event Action OnGameInitialized;
|
||||||
|
|
||||||
// Pause state
|
|
||||||
private bool _isPaused = false;
|
|
||||||
|
|
||||||
// List of pausable components controlled by this manager
|
// List of pausable components controlled by this manager
|
||||||
private List<IPausable> _pausableComponents = new List<IPausable>();
|
private List<IPausable> _pausableComponents = new List<IPausable>();
|
||||||
|
|
||||||
// IPausable implementation
|
|
||||||
public bool IsPaused => _isPaused;
|
|
||||||
|
|
||||||
// Photo sequence state
|
// Photo sequence state
|
||||||
private bool _isPhotoSequenceActive = false;
|
private bool _isPhotoSequenceActive = false;
|
||||||
private Monster _currentPhotoTarget = null;
|
private Monster _currentPhotoTarget = null;
|
||||||
private Dictionary<IPausable, bool> _pauseStateBackup = new Dictionary<IPausable, bool>();
|
private float _capturedProximity = 0f;
|
||||||
private float _capturedProximity = 0f; // New: tracks how close to target the photo was taken (0-1)
|
|
||||||
|
|
||||||
// List of components to exempt from pausing during photo sequence
|
// List of components to exempt from pausing during photo sequence
|
||||||
private List<IPausable> _exemptFromPhotoSequencePausing = new List<IPausable>();
|
private List<IPausable> _exemptFromPhotoSequencePausing = new List<IPausable>();
|
||||||
@@ -101,7 +96,6 @@ namespace Minigames.DivingForPictures
|
|||||||
// Photo sequence events
|
// Photo sequence events
|
||||||
public event Action<Monster> OnPhotoSequenceStarted;
|
public event Action<Monster> OnPhotoSequenceStarted;
|
||||||
public event Action<Monster, float> OnPhotoSequenceCompleted; // Now includes proximity score
|
public event Action<Monster, float> OnPhotoSequenceCompleted; // Now includes proximity score
|
||||||
public event Action<float> OnPhotoSequenceProgressUpdated;
|
|
||||||
|
|
||||||
private static DivingGameManager _instance = null;
|
private static DivingGameManager _instance = null;
|
||||||
private static bool _isQuitting = false;
|
private static bool _isQuitting = false;
|
||||||
@@ -113,8 +107,8 @@ namespace Minigames.DivingForPictures
|
|||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
settings = GameManager.GetSettingsObject<IDivingMinigameSettings>();
|
_settings = GameManager.GetSettingsObject<IDivingMinigameSettings>();
|
||||||
currentSpawnProbability = settings?.BaseSpawnProbability ?? 0.2f;
|
_currentSpawnProbability = _settings?.BaseSpawnProbability ?? 0.2f;
|
||||||
|
|
||||||
if (_instance == null)
|
if (_instance == null)
|
||||||
{
|
{
|
||||||
@@ -124,6 +118,9 @@ namespace Minigames.DivingForPictures
|
|||||||
{
|
{
|
||||||
Destroy(gameObject);
|
Destroy(gameObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure any previous run state is reset when this manager awakes
|
||||||
|
_isGameOver = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnApplicationQuit()
|
private void OnApplicationQuit()
|
||||||
@@ -133,44 +130,8 @@ namespace Minigames.DivingForPictures
|
|||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
// Find PauseMenu and subscribe to its events
|
// Register for post-boot initialization
|
||||||
PauseMenu pauseMenu = PauseMenu.Instance;
|
BootCompletionService.RegisterInitAction(InitializePostBoot);
|
||||||
if (pauseMenu != null)
|
|
||||||
{
|
|
||||||
pauseMenu.OnGamePaused += Pause;
|
|
||||||
pauseMenu.OnGameResumed += DoResume;
|
|
||||||
|
|
||||||
Logging.Debug("[DivingGameManager] Subscribed to PauseMenu events");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Logging.Warning("[DivingGameManager] PauseMenu not found. Pause functionality won't work properly.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register this manager with the global GameManager
|
|
||||||
if (GameManager.Instance != null)
|
|
||||||
{
|
|
||||||
GameManager.Instance.RegisterPausableComponent(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Subscribe to SceneOrientationEnforcer's event
|
|
||||||
if (SceneOrientationEnforcer.Instance != null)
|
|
||||||
{
|
|
||||||
SceneOrientationEnforcer.Instance.OnOrientationCorrect += InitializeGame;
|
|
||||||
SceneOrientationEnforcer.Instance.OnOrientationIncorrect += Pause;
|
|
||||||
|
|
||||||
// If orientation is already correct, initialize right away
|
|
||||||
// This prevents issues if the orientation was already correct before subscription
|
|
||||||
if (SceneOrientationEnforcer.Instance.IsOrientationCorrect())
|
|
||||||
{
|
|
||||||
InitializeGame();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Logging.Warning("[DivingGameManager] SceneOrientationEnforcer not found. Initializing game immediately.");
|
|
||||||
InitializeGame();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Subscribe to player damage events (this doesn't depend on initialization)
|
// Subscribe to player damage events (this doesn't depend on initialization)
|
||||||
PlayerCollisionBehavior.OnDamageTaken += OnPlayerDamageTaken;
|
PlayerCollisionBehavior.OnDamageTaken += OnPlayerDamageTaken;
|
||||||
@@ -189,6 +150,7 @@ namespace Minigames.DivingForPictures
|
|||||||
viewfinderManager.OnViewfinderTappedDuringAnimation += OnViewfinderTappedDuringAnimation;
|
viewfinderManager.OnViewfinderTappedDuringAnimation += OnViewfinderTappedDuringAnimation;
|
||||||
viewfinderManager.OnReverseAnimationStarted += OnReverseAnimationStarted;
|
viewfinderManager.OnReverseAnimationStarted += OnReverseAnimationStarted;
|
||||||
|
|
||||||
|
// TODO: Give this a second look and make sure this is correct
|
||||||
// Add the viewfinder manager to exempt list to ensure it keeps working during photo sequences
|
// Add the viewfinder manager to exempt list to ensure it keeps working during photo sequences
|
||||||
if (viewfinderManager is IPausable viewfinderPausable)
|
if (viewfinderManager is IPausable viewfinderPausable)
|
||||||
{
|
{
|
||||||
@@ -197,6 +159,36 @@ namespace Minigames.DivingForPictures
|
|||||||
}
|
}
|
||||||
|
|
||||||
OnMonsterSpawned += DoMonsterSpawned;
|
OnMonsterSpawned += DoMonsterSpawned;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializePostBoot()
|
||||||
|
{
|
||||||
|
// Register this manager with the global GameManager
|
||||||
|
if (GameManager.Instance != null)
|
||||||
|
{
|
||||||
|
GameManager.Instance.RegisterPausableComponent(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subscribe to SceneOrientationEnforcer's event
|
||||||
|
if (SceneOrientationEnforcer.Instance != null)
|
||||||
|
{
|
||||||
|
// TODO: This is a bit of a hack to make sure the game is initialized after the orientation is correct
|
||||||
|
SceneOrientationEnforcer.Instance.OnOrientationCorrect += InitializeGame;
|
||||||
|
SceneOrientationEnforcer.Instance.OnOrientationIncorrect += Pause;
|
||||||
|
|
||||||
|
// If orientation is already correct, initialize right away
|
||||||
|
// This prevents issues if the orientation was already correct before subscription
|
||||||
|
if (SceneOrientationEnforcer.Instance.IsOrientationCorrect())
|
||||||
|
{
|
||||||
|
InitializeGame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logging.Warning("[DivingGameManager] SceneOrientationEnforcer not found. Initializing game immediately.");
|
||||||
|
InitializeGame();
|
||||||
|
}
|
||||||
|
|
||||||
CinematicsManager.Instance.OnCinematicStopped += EndGame;
|
CinematicsManager.Instance.OnCinematicStopped += EndGame;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,14 +203,6 @@ namespace Minigames.DivingForPictures
|
|||||||
SceneOrientationEnforcer.Instance.OnOrientationIncorrect -= Pause;
|
SceneOrientationEnforcer.Instance.OnOrientationIncorrect -= Pause;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unsubscribe from PauseMenu events
|
|
||||||
PauseMenu pauseMenu = PauseMenu.Instance;
|
|
||||||
if (pauseMenu != null)
|
|
||||||
{
|
|
||||||
pauseMenu.OnGamePaused -= Pause;
|
|
||||||
pauseMenu.OnGameResumed -= DoResume;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unregister from GameManager
|
// Unregister from GameManager
|
||||||
if (GameManager.Instance != null)
|
if (GameManager.Instance != null)
|
||||||
{
|
{
|
||||||
@@ -241,19 +225,19 @@ namespace Minigames.DivingForPictures
|
|||||||
|
|
||||||
private void Update()
|
private void Update()
|
||||||
{
|
{
|
||||||
timeSinceLastSpawn += Time.deltaTime;
|
_timeSinceLastSpawn += Time.deltaTime;
|
||||||
|
|
||||||
// Gradually increase spawn probability over time
|
// Gradually increase spawn probability over time
|
||||||
float previousProbability = currentSpawnProbability;
|
float previousProbability = _currentSpawnProbability;
|
||||||
if (currentSpawnProbability < settings.MaxSpawnProbability)
|
if (_currentSpawnProbability < _settings.MaxSpawnProbability)
|
||||||
{
|
{
|
||||||
currentSpawnProbability += settings.ProbabilityIncreaseRate * Time.deltaTime;
|
_currentSpawnProbability += _settings.ProbabilityIncreaseRate * Time.deltaTime;
|
||||||
currentSpawnProbability = Mathf.Min(currentSpawnProbability, settings.MaxSpawnProbability);
|
_currentSpawnProbability = Mathf.Min(_currentSpawnProbability, _settings.MaxSpawnProbability);
|
||||||
|
|
||||||
// Only fire event if probability changed significantly
|
// Only fire event if probability changed significantly
|
||||||
if (Mathf.Abs(currentSpawnProbability - previousProbability) > 0.01f)
|
if (Mathf.Abs(_currentSpawnProbability - previousProbability) > 0.01f)
|
||||||
{
|
{
|
||||||
OnSpawnProbabilityChanged?.Invoke(currentSpawnProbability);
|
OnSpawnProbabilityChanged?.Invoke(_currentSpawnProbability);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -268,14 +252,14 @@ namespace Minigames.DivingForPictures
|
|||||||
// If we're surfacing, don't spawn new monsters
|
// If we're surfacing, don't spawn new monsters
|
||||||
if (_isSurfacing) return;
|
if (_isSurfacing) return;
|
||||||
|
|
||||||
bool forceSpawn = timeSinceLastSpawn >= settings.GuaranteedSpawnTime;
|
bool forceSpawn = _timeSinceLastSpawn >= _settings.GuaranteedSpawnTime;
|
||||||
bool onCooldown = timeSinceLastSpawn < settings.SpawnCooldown;
|
bool onCooldown = _timeSinceLastSpawn < _settings.SpawnCooldown;
|
||||||
|
|
||||||
// Don't spawn if on cooldown, unless forced
|
// Don't spawn if on cooldown, unless forced
|
||||||
if (onCooldown && !forceSpawn) return;
|
if (onCooldown && !forceSpawn) return;
|
||||||
|
|
||||||
// Check probability or forced spawn
|
// Check probability or forced spawn
|
||||||
if (forceSpawn || UnityEngine.Random.value <= currentSpawnProbability)
|
if (forceSpawn || UnityEngine.Random.value <= _currentSpawnProbability)
|
||||||
{
|
{
|
||||||
// Pick a random spawn point from this tile
|
// Pick a random spawn point from this tile
|
||||||
MonsterSpawnPoint spawnPoint = spawnPoints[UnityEngine.Random.Range(0, spawnPoints.Length)];
|
MonsterSpawnPoint spawnPoint = spawnPoints[UnityEngine.Random.Range(0, spawnPoints.Length)];
|
||||||
@@ -284,10 +268,10 @@ namespace Minigames.DivingForPictures
|
|||||||
SpawnMonster(spawnPoint.transform);
|
SpawnMonster(spawnPoint.transform);
|
||||||
|
|
||||||
// Reset timer and adjust probability
|
// Reset timer and adjust probability
|
||||||
lastSpawnTime = Time.time;
|
_lastSpawnTime = Time.time;
|
||||||
timeSinceLastSpawn = 0f;
|
_timeSinceLastSpawn = 0f;
|
||||||
currentSpawnProbability = settings.BaseSpawnProbability;
|
_currentSpawnProbability = _settings.BaseSpawnProbability;
|
||||||
OnSpawnProbabilityChanged?.Invoke(currentSpawnProbability);
|
OnSpawnProbabilityChanged?.Invoke(_currentSpawnProbability);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,14 +319,14 @@ namespace Minigames.DivingForPictures
|
|||||||
private void DoPictureTaken(Monster monster)
|
private void DoPictureTaken(Monster monster)
|
||||||
{
|
{
|
||||||
// Calculate points based on depth
|
// Calculate points based on depth
|
||||||
int depthBonus = Mathf.FloorToInt(Mathf.Abs(monster.transform.position.y) * settings.DepthMultiplier);
|
int depthBonus = Mathf.FloorToInt(Mathf.Abs(monster.transform.position.y) * _settings.DepthMultiplier);
|
||||||
int pointsAwarded = settings.BasePoints + depthBonus;
|
int pointsAwarded = _settings.BasePoints + depthBonus;
|
||||||
|
|
||||||
// Add score
|
// Add score
|
||||||
playerScore += pointsAwarded;
|
_playerScore += pointsAwarded;
|
||||||
|
|
||||||
// Fire events
|
// Fire events
|
||||||
OnScoreChanged?.Invoke(playerScore);
|
OnScoreChanged?.Invoke(_playerScore);
|
||||||
OnPictureTaken?.Invoke(monster, pointsAwarded);
|
OnPictureTaken?.Invoke(monster, pointsAwarded);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,13 +335,13 @@ namespace Minigames.DivingForPictures
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void OnPlayerDamageTaken()
|
private void OnPlayerDamageTaken()
|
||||||
{
|
{
|
||||||
if (isGameOver) return;
|
if (_isGameOver) return;
|
||||||
|
|
||||||
// Break the next rope in sequence
|
// Break the next rope in sequence
|
||||||
BreakNextRope();
|
BreakNextRope();
|
||||||
|
|
||||||
// Check if all ropes are broken
|
// Check if all ropes are broken
|
||||||
if (currentRopeIndex >= playerRopes.Length)
|
if (_currentRopeIndex >= playerRopes.Length)
|
||||||
{
|
{
|
||||||
TriggerGameOver();
|
TriggerGameOver();
|
||||||
deathAudioPlayer.Play();
|
deathAudioPlayer.Play();
|
||||||
@@ -365,7 +349,7 @@ namespace Minigames.DivingForPictures
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Notify listeners about rope break and remaining ropes
|
// Notify listeners about rope break and remaining ropes
|
||||||
int remainingRopes = playerRopes.Length - currentRopeIndex;
|
int remainingRopes = playerRopes.Length - _currentRopeIndex;
|
||||||
OnRopeBroken?.Invoke(remainingRopes);
|
OnRopeBroken?.Invoke(remainingRopes);
|
||||||
|
|
||||||
Logging.Debug($"[DivingGameManager] Rope broken! {remainingRopes} ropes remaining.");
|
Logging.Debug($"[DivingGameManager] Rope broken! {remainingRopes} ropes remaining.");
|
||||||
@@ -377,9 +361,9 @@ namespace Minigames.DivingForPictures
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void BreakNextRope()
|
private void BreakNextRope()
|
||||||
{
|
{
|
||||||
if (currentRopeIndex < playerRopes.Length)
|
if (_currentRopeIndex < playerRopes.Length)
|
||||||
{
|
{
|
||||||
RopeBreaker ropeToBreak = playerRopes[currentRopeIndex];
|
RopeBreaker ropeToBreak = playerRopes[_currentRopeIndex];
|
||||||
|
|
||||||
if (ropeToBreak != null)
|
if (ropeToBreak != null)
|
||||||
{
|
{
|
||||||
@@ -388,11 +372,11 @@ namespace Minigames.DivingForPictures
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logging.Warning($"[DivingGameManager] Rope at index {currentRopeIndex} is null!");
|
Logging.Warning($"[DivingGameManager] Rope at index {_currentRopeIndex} is null!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move to the next rope regardless if current was null
|
// Move to the next rope regardless if current was null
|
||||||
currentRopeIndex++;
|
_currentRopeIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -401,7 +385,7 @@ namespace Minigames.DivingForPictures
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void ForceBreakRope()
|
public void ForceBreakRope()
|
||||||
{
|
{
|
||||||
if (!isGameOver)
|
if (!_isGameOver)
|
||||||
{
|
{
|
||||||
OnPlayerDamageTaken();
|
OnPlayerDamageTaken();
|
||||||
}
|
}
|
||||||
@@ -412,9 +396,9 @@ namespace Minigames.DivingForPictures
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void TriggerGameOver()
|
private void TriggerGameOver()
|
||||||
{
|
{
|
||||||
if (isGameOver) return;
|
if (_isGameOver) return;
|
||||||
|
|
||||||
isGameOver = true;
|
_isGameOver = true;
|
||||||
Logging.Debug("[DivingGameManager] Game Over! All ropes broken. Starting surfacing sequence...");
|
Logging.Debug("[DivingGameManager] Game Over! All ropes broken. Starting surfacing sequence...");
|
||||||
|
|
||||||
// Fire game over event
|
// Fire game over event
|
||||||
@@ -450,8 +434,8 @@ namespace Minigames.DivingForPictures
|
|||||||
public void ResetRopeSystem()
|
public void ResetRopeSystem()
|
||||||
{
|
{
|
||||||
// Reset rope state
|
// Reset rope state
|
||||||
currentRopeIndex = 0;
|
_currentRopeIndex = 0;
|
||||||
isGameOver = false;
|
_isGameOver = false;
|
||||||
|
|
||||||
// Restore all broken ropes
|
// Restore all broken ropes
|
||||||
if (playerRopes != null)
|
if (playerRopes != null)
|
||||||
@@ -477,8 +461,11 @@ namespace Minigames.DivingForPictures
|
|||||||
|
|
||||||
_isSurfacing = true;
|
_isSurfacing = true;
|
||||||
|
|
||||||
|
// TODO: Call it here?
|
||||||
|
UIPageController.Instance.HideAllUI();
|
||||||
|
|
||||||
// 1. Initiate smooth velocity transition to surfacing speed
|
// 1. Initiate smooth velocity transition to surfacing speed
|
||||||
float targetVelocityFactor = -1.0f * settings.SurfacingSpeedFactor;
|
float targetVelocityFactor = -1.0f * _settings.SurfacingSpeedFactor;
|
||||||
SetVelocityFactor(targetVelocityFactor);
|
SetVelocityFactor(targetVelocityFactor);
|
||||||
|
|
||||||
// 2. Find and notify trench tile spawner about direction change (for spawning/despawning logic)
|
// 2. Find and notify trench tile spawner about direction change (for spawning/despawning logic)
|
||||||
@@ -497,7 +484,7 @@ namespace Minigames.DivingForPictures
|
|||||||
tileSpawner.StartSurfacing();
|
tileSpawner.StartSurfacing();
|
||||||
|
|
||||||
// Immediately send current velocity factor
|
// Immediately send current velocity factor
|
||||||
tileSpawner.OnVelocityFactorChanged(currentVelocityFactor);
|
tileSpawner.OnVelocityFactorChanged(_currentVelocityFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle the Rock object - disable components and animate it falling offscreen
|
// Handle the Rock object - disable components and animate it falling offscreen
|
||||||
@@ -565,15 +552,15 @@ namespace Minigames.DivingForPictures
|
|||||||
obstacleSpawner.StartSurfacing();
|
obstacleSpawner.StartSurfacing();
|
||||||
|
|
||||||
// Immediately send current velocity factor
|
// Immediately send current velocity factor
|
||||||
obstacleSpawner.OnVelocityFactorChanged(currentVelocityFactor);
|
obstacleSpawner.OnVelocityFactorChanged(_currentVelocityFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start the surfacing sequence coroutine
|
// Start the surfacing sequence coroutine
|
||||||
if (surfacingSequenceCoroutine != null)
|
if (_surfacingSequenceCoroutine != null)
|
||||||
{
|
{
|
||||||
StopCoroutine(surfacingSequenceCoroutine);
|
StopCoroutine(_surfacingSequenceCoroutine);
|
||||||
}
|
}
|
||||||
surfacingSequenceCoroutine = StartCoroutine(SurfacingSequence());
|
_surfacingSequenceCoroutine = StartCoroutine(SurfacingSequence());
|
||||||
|
|
||||||
Logging.Debug($"[DivingGameManager] Started surfacing with target velocity factor: {targetVelocityFactor}");
|
Logging.Debug($"[DivingGameManager] Started surfacing with target velocity factor: {targetVelocityFactor}");
|
||||||
}
|
}
|
||||||
@@ -649,7 +636,7 @@ namespace Minigames.DivingForPictures
|
|||||||
private IEnumerator SurfacingSequence()
|
private IEnumerator SurfacingSequence()
|
||||||
{
|
{
|
||||||
// Wait for the configured delay
|
// Wait for the configured delay
|
||||||
yield return new WaitForSeconds(settings.SurfacingSpawnDelay);
|
yield return new WaitForSeconds(_settings.SurfacingSpawnDelay);
|
||||||
|
|
||||||
// Find tile spawner and tell it to stop spawning
|
// Find tile spawner and tell it to stop spawning
|
||||||
TrenchTileSpawner tileSpawner = FindFirstObjectByType<TrenchTileSpawner>();
|
TrenchTileSpawner tileSpawner = FindFirstObjectByType<TrenchTileSpawner>();
|
||||||
@@ -686,7 +673,6 @@ namespace Minigames.DivingForPictures
|
|||||||
// Call this when the game ends
|
// Call this when the game ends
|
||||||
public void EndGame()
|
public void EndGame()
|
||||||
{
|
{
|
||||||
// TODO: Investigate why called twice
|
|
||||||
CinematicsManager.Instance.OnCinematicStopped -= EndGame;
|
CinematicsManager.Instance.OnCinematicStopped -= EndGame;
|
||||||
// Start the end game sequence that grants a booster, waits for the UI animation, then shows Game Over.
|
// Start the end game sequence that grants a booster, waits for the UI animation, then shows Game Over.
|
||||||
StartCoroutine(EndGameSequence());
|
StartCoroutine(EndGameSequence());
|
||||||
@@ -695,7 +681,7 @@ namespace Minigames.DivingForPictures
|
|||||||
private IEnumerator EndGameSequence()
|
private IEnumerator EndGameSequence()
|
||||||
{
|
{
|
||||||
// Clean up active monsters
|
// Clean up active monsters
|
||||||
foreach (var monster in activeMonsters.ToArray())
|
foreach (var monster in _activeMonsters.ToArray())
|
||||||
{
|
{
|
||||||
if (monster != null)
|
if (monster != null)
|
||||||
{
|
{
|
||||||
@@ -703,7 +689,7 @@ namespace Minigames.DivingForPictures
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
activeMonsters.Clear();
|
_activeMonsters.Clear();
|
||||||
|
|
||||||
// 1) Call the booster pack giver if available
|
// 1) Call the booster pack giver if available
|
||||||
bool completed = false;
|
bool completed = false;
|
||||||
@@ -714,6 +700,7 @@ namespace Minigames.DivingForPictures
|
|||||||
UnityAction onDone = null;
|
UnityAction onDone = null;
|
||||||
onDone = () => { completed = true; giver.OnCompleted.RemoveListener(onDone); };
|
onDone = () => { completed = true; giver.OnCompleted.RemoveListener(onDone); };
|
||||||
giver.OnCompleted.AddListener(onDone);
|
giver.OnCompleted.AddListener(onDone);
|
||||||
|
UIPageController.Instance.ShowAllUI();
|
||||||
giver.GiveBoosterPack();
|
giver.GiveBoosterPack();
|
||||||
|
|
||||||
// 2) Wait for it to finish (with a safety timeout in case it's not wired)
|
// 2) Wait for it to finish (with a safety timeout in case it's not wired)
|
||||||
@@ -735,7 +722,7 @@ namespace Minigames.DivingForPictures
|
|||||||
CinematicsManager.Instance.ShowGameOverScreen();
|
CinematicsManager.Instance.ShowGameOverScreen();
|
||||||
|
|
||||||
// Final score could be saved to player prefs or other persistence
|
// Final score could be saved to player prefs or other persistence
|
||||||
Logging.Debug($"Final Score: {playerScore}");
|
Logging.Debug($"Final Score: {_playerScore}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -744,12 +731,12 @@ namespace Minigames.DivingForPictures
|
|||||||
/// <param name="targetFactor">Target velocity factor (e.g., -1.0 for surfacing speed)</param>
|
/// <param name="targetFactor">Target velocity factor (e.g., -1.0 for surfacing speed)</param>
|
||||||
public void SetVelocityFactor(float targetFactor)
|
public void SetVelocityFactor(float targetFactor)
|
||||||
{
|
{
|
||||||
if (velocityTransitionCoroutine != null)
|
if (_velocityTransitionCoroutine != null)
|
||||||
{
|
{
|
||||||
StopCoroutine(velocityTransitionCoroutine);
|
StopCoroutine(_velocityTransitionCoroutine);
|
||||||
}
|
}
|
||||||
|
|
||||||
velocityTransitionCoroutine = StartCoroutine(TransitionVelocityFactor(targetFactor));
|
_velocityTransitionCoroutine = StartCoroutine(TransitionVelocityFactor(targetFactor));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -757,29 +744,29 @@ namespace Minigames.DivingForPictures
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private IEnumerator<WaitForEndOfFrame> TransitionVelocityFactor(float targetFactor)
|
private IEnumerator<WaitForEndOfFrame> TransitionVelocityFactor(float targetFactor)
|
||||||
{
|
{
|
||||||
float startFactor = currentVelocityFactor;
|
float startFactor = _currentVelocityFactor;
|
||||||
float elapsed = 0f;
|
float elapsed = 0f;
|
||||||
|
|
||||||
while (elapsed < settings.SpeedTransitionDuration)
|
while (elapsed < _settings.SpeedTransitionDuration)
|
||||||
{
|
{
|
||||||
elapsed += Time.deltaTime;
|
elapsed += Time.deltaTime;
|
||||||
float t = Mathf.Clamp01(elapsed / settings.SpeedTransitionDuration);
|
float t = Mathf.Clamp01(elapsed / _settings.SpeedTransitionDuration);
|
||||||
|
|
||||||
// Smooth step interpolation
|
// Smooth step interpolation
|
||||||
float smoothStep = t * t * (3f - 2f * t);
|
float smoothStep = t * t * (3f - 2f * t);
|
||||||
|
|
||||||
currentVelocityFactor = Mathf.Lerp(startFactor, targetFactor, smoothStep);
|
_currentVelocityFactor = Mathf.Lerp(startFactor, targetFactor, smoothStep);
|
||||||
|
|
||||||
// Notify listeners about the velocity factor change
|
// Notify listeners about the velocity factor change
|
||||||
OnVelocityFactorChanged?.Invoke(currentVelocityFactor);
|
OnVelocityFactorChanged?.Invoke(_currentVelocityFactor);
|
||||||
|
|
||||||
yield return null;
|
yield return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentVelocityFactor = targetFactor;
|
_currentVelocityFactor = targetFactor;
|
||||||
|
|
||||||
// Final assignment to ensure exact target value
|
// Final assignment to ensure exact target value
|
||||||
OnVelocityFactorChanged?.Invoke(currentVelocityFactor);
|
OnVelocityFactorChanged?.Invoke(_currentVelocityFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -793,7 +780,7 @@ namespace Minigames.DivingForPictures
|
|||||||
_pausableComponents.Add(component);
|
_pausableComponents.Add(component);
|
||||||
|
|
||||||
// If the game is already paused, pause the component immediately
|
// If the game is already paused, pause the component immediately
|
||||||
if (_isPaused)
|
if (GameManager.Instance.IsPaused)
|
||||||
{
|
{
|
||||||
component.Pause();
|
component.Pause();
|
||||||
}
|
}
|
||||||
@@ -820,15 +807,15 @@ namespace Minigames.DivingForPictures
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Pause()
|
public void Pause()
|
||||||
{
|
{
|
||||||
|
// Ignore pause requests once the game has reached Game Over
|
||||||
|
if (_isGameOver) return;
|
||||||
DoPause();
|
DoPause();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DoPause(bool turnOffGameInput = true)
|
public void DoPause(bool turnOffGameInput = true)
|
||||||
{
|
{
|
||||||
if (_isPaused) return; // Already paused
|
// Ignore pause requests once the game has ended
|
||||||
|
if (_isGameOver) return;
|
||||||
_isPaused = true;
|
|
||||||
|
|
||||||
// Pause all registered components
|
// Pause all registered components
|
||||||
foreach (var component in _pausableComponents)
|
foreach (var component in _pausableComponents)
|
||||||
{
|
{
|
||||||
@@ -847,10 +834,8 @@ namespace Minigames.DivingForPictures
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void DoResume()
|
public void DoResume()
|
||||||
{
|
{
|
||||||
if (!_isPaused) return; // Already running
|
// Ignore resume requests once the game has ended
|
||||||
|
if (_isGameOver) return;
|
||||||
_isPaused = false;
|
|
||||||
|
|
||||||
// Resume all registered components
|
// Resume all registered components
|
||||||
foreach (var component in _pausableComponents)
|
foreach (var component in _pausableComponents)
|
||||||
{
|
{
|
||||||
@@ -938,23 +923,23 @@ namespace Minigames.DivingForPictures
|
|||||||
if (monster == null) return;
|
if (monster == null) return;
|
||||||
|
|
||||||
// Calculate base points from depth
|
// Calculate base points from depth
|
||||||
int depthBonus = Mathf.FloorToInt(Mathf.Abs(monster.transform.position.y) * settings.DepthMultiplier);
|
int depthBonus = Mathf.FloorToInt(Mathf.Abs(monster.transform.position.y) * _settings.DepthMultiplier);
|
||||||
|
|
||||||
// Apply proximity multiplier (0-100%)
|
// Apply proximity multiplier (0-100%)
|
||||||
float proximityMultiplier = Mathf.Clamp01(proximity); // Ensure it's in 0-1 range
|
float proximityMultiplier = Mathf.Clamp01(proximity); // Ensure it's in 0-1 range
|
||||||
int proximityBonus = Mathf.RoundToInt(settings.BasePoints * proximityMultiplier);
|
int proximityBonus = Mathf.RoundToInt(_settings.BasePoints * proximityMultiplier);
|
||||||
|
|
||||||
// Calculate total score
|
// Calculate total score
|
||||||
int pointsAwarded = settings.BasePoints + proximityBonus + depthBonus;
|
int pointsAwarded = _settings.BasePoints + proximityBonus + depthBonus;
|
||||||
|
|
||||||
Logging.Debug($"[DivingGameManager] Picture score calculation: base={proximityBonus} (proximity={proximity:F2}), " +
|
Logging.Debug($"[DivingGameManager] Picture score calculation: base={proximityBonus} (proximity={proximity:F2}), " +
|
||||||
$"depth bonus={depthBonus}, total={pointsAwarded}");
|
$"depth bonus={depthBonus}, total={pointsAwarded}");
|
||||||
|
|
||||||
// Add score
|
// Add score
|
||||||
playerScore += pointsAwarded;
|
_playerScore += pointsAwarded;
|
||||||
|
|
||||||
// Fire events
|
// Fire events
|
||||||
OnScoreChanged?.Invoke(playerScore);
|
OnScoreChanged?.Invoke(_playerScore);
|
||||||
OnPictureTaken?.Invoke(monster, pointsAwarded);
|
OnPictureTaken?.Invoke(monster, pointsAwarded);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1061,14 +1046,14 @@ namespace Minigames.DivingForPictures
|
|||||||
monster.OnMonsterDespawned += DoMonsterDespawned;
|
monster.OnMonsterDespawned += DoMonsterDespawned;
|
||||||
|
|
||||||
// Add to active monsters list
|
// Add to active monsters list
|
||||||
activeMonsters.Add(monster);
|
_activeMonsters.Add(monster);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DoMonsterDespawned(Monster monster)
|
private void DoMonsterDespawned(Monster monster)
|
||||||
{
|
{
|
||||||
// Remove from active list
|
// Remove from active list
|
||||||
activeMonsters.Remove(monster);
|
_activeMonsters.Remove(monster);
|
||||||
|
|
||||||
// Unsubscribe from monster events
|
// Unsubscribe from monster events
|
||||||
if (monster != null)
|
if (monster != null)
|
||||||
|
|||||||
@@ -59,12 +59,6 @@ namespace Minigames.DivingForPictures
|
|||||||
private float _screenNormalizationFactor = 1.0f;
|
private float _screenNormalizationFactor = 1.0f;
|
||||||
private IDivingMinigameSettings _settings;
|
private IDivingMinigameSettings _settings;
|
||||||
|
|
||||||
// Pause state
|
|
||||||
private bool _isPaused = false;
|
|
||||||
|
|
||||||
// IPausable implementation
|
|
||||||
public bool IsPaused => _isPaused;
|
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
_collider = GetComponent<Collider2D>();
|
_collider = GetComponent<Collider2D>();
|
||||||
@@ -124,7 +118,7 @@ namespace Minigames.DivingForPictures
|
|||||||
private void OnEnable()
|
private void OnEnable()
|
||||||
{
|
{
|
||||||
// Only start coroutines if not paused
|
// Only start coroutines if not paused
|
||||||
if (!_isPaused)
|
if (!GameManager.Instance.IsPaused)
|
||||||
{
|
{
|
||||||
StartObstacleCoroutines();
|
StartObstacleCoroutines();
|
||||||
}
|
}
|
||||||
@@ -143,9 +137,6 @@ namespace Minigames.DivingForPictures
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Pause()
|
public void Pause()
|
||||||
{
|
{
|
||||||
if (_isPaused) return; // Already paused
|
|
||||||
|
|
||||||
_isPaused = true;
|
|
||||||
StopObstacleCoroutines();
|
StopObstacleCoroutines();
|
||||||
|
|
||||||
Logging.Debug($"[FloatingObstacle] Paused obstacle: {name}");
|
Logging.Debug($"[FloatingObstacle] Paused obstacle: {name}");
|
||||||
@@ -156,9 +147,6 @@ namespace Minigames.DivingForPictures
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void DoResume()
|
public void DoResume()
|
||||||
{
|
{
|
||||||
if (!_isPaused) return; // Already running
|
|
||||||
|
|
||||||
_isPaused = false;
|
|
||||||
StartObstacleCoroutines();
|
StartObstacleCoroutines();
|
||||||
|
|
||||||
Logging.Debug($"[FloatingObstacle] Resumed obstacle: {name}");
|
Logging.Debug($"[FloatingObstacle] Resumed obstacle: {name}");
|
||||||
|
|||||||
@@ -43,12 +43,6 @@ namespace Minigames.DivingForPictures
|
|||||||
private bool _isSurfacing = false; // Flag to track surfacing state
|
private bool _isSurfacing = false; // Flag to track surfacing state
|
||||||
private float _velocityFactor = 1.0f; // Current velocity factor from the game manager
|
private float _velocityFactor = 1.0f; // Current velocity factor from the game manager
|
||||||
|
|
||||||
// Pause state
|
|
||||||
private bool _isPaused = false;
|
|
||||||
|
|
||||||
// IPausable implementation
|
|
||||||
public bool IsPaused => _isPaused;
|
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
_mainCamera = UnityEngine.Camera.main;
|
_mainCamera = UnityEngine.Camera.main;
|
||||||
@@ -127,10 +121,6 @@ namespace Minigames.DivingForPictures
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Pause()
|
public void Pause()
|
||||||
{
|
{
|
||||||
if (_isPaused) return; // Already paused
|
|
||||||
|
|
||||||
_isPaused = true;
|
|
||||||
|
|
||||||
// Stop spawning coroutine
|
// Stop spawning coroutine
|
||||||
if (_spawnCoroutine != null)
|
if (_spawnCoroutine != null)
|
||||||
{
|
{
|
||||||
@@ -159,10 +149,6 @@ namespace Minigames.DivingForPictures
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void DoResume()
|
public void DoResume()
|
||||||
{
|
{
|
||||||
if (!_isPaused) return; // Already running
|
|
||||||
|
|
||||||
_isPaused = false;
|
|
||||||
|
|
||||||
// Restart spawning coroutine if not in surfacing mode
|
// Restart spawning coroutine if not in surfacing mode
|
||||||
if (!_isSurfacing)
|
if (!_isSurfacing)
|
||||||
{
|
{
|
||||||
@@ -190,7 +176,7 @@ namespace Minigames.DivingForPictures
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void StartSpawnCoroutine()
|
private void StartSpawnCoroutine()
|
||||||
{
|
{
|
||||||
if (_spawnCoroutine == null && !_isPaused && !_isSurfacing)
|
if (_spawnCoroutine == null && !GameManager.Instance.IsPaused && !_isSurfacing)
|
||||||
{
|
{
|
||||||
_spawnCoroutine = StartCoroutine(SpawnObstacleRoutine());
|
_spawnCoroutine = StartCoroutine(SpawnObstacleRoutine());
|
||||||
}
|
}
|
||||||
@@ -201,7 +187,7 @@ namespace Minigames.DivingForPictures
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void StartMoveCoroutine()
|
private void StartMoveCoroutine()
|
||||||
{
|
{
|
||||||
if (_moveCoroutine == null && !_isPaused)
|
if (_moveCoroutine == null && !GameManager.Instance.IsPaused)
|
||||||
{
|
{
|
||||||
_moveCoroutine = StartCoroutine(MoveObstaclesRoutine());
|
_moveCoroutine = StartCoroutine(MoveObstaclesRoutine());
|
||||||
}
|
}
|
||||||
@@ -212,7 +198,7 @@ namespace Minigames.DivingForPictures
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void StartDespawnCoroutine()
|
private void StartDespawnCoroutine()
|
||||||
{
|
{
|
||||||
if (_despawnCoroutine == null && !_isPaused)
|
if (_despawnCoroutine == null && !GameManager.Instance.IsPaused)
|
||||||
{
|
{
|
||||||
_despawnCoroutine = StartCoroutine(DespawnObstaclesRoutine());
|
_despawnCoroutine = StartCoroutine(DespawnObstaclesRoutine());
|
||||||
}
|
}
|
||||||
@@ -553,7 +539,7 @@ namespace Minigames.DivingForPictures
|
|||||||
obstacleComponent.SetSpawner(this);
|
obstacleComponent.SetSpawner(this);
|
||||||
|
|
||||||
// If spawner is already paused, pause the obstacle immediately
|
// If spawner is already paused, pause the obstacle immediately
|
||||||
if (_isPaused)
|
if (GameManager.Instance.IsPaused)
|
||||||
{
|
{
|
||||||
obstacleComponent.Pause();
|
obstacleComponent.Pause();
|
||||||
}
|
}
|
||||||
@@ -677,7 +663,7 @@ namespace Minigames.DivingForPictures
|
|||||||
{
|
{
|
||||||
Logging.Debug("[ObstacleSpawner] Started spawning coroutine");
|
Logging.Debug("[ObstacleSpawner] Started spawning coroutine");
|
||||||
|
|
||||||
while (enabled && gameObject.activeInHierarchy && !_isPaused && !_isSurfacing)
|
while (enabled && gameObject.activeInHierarchy && !GameManager.Instance.IsPaused && !_isSurfacing)
|
||||||
{
|
{
|
||||||
// Calculate next spawn time with variation
|
// Calculate next spawn time with variation
|
||||||
float nextSpawnTime = _settings.ObstacleSpawnInterval +
|
float nextSpawnTime = _settings.ObstacleSpawnInterval +
|
||||||
@@ -707,7 +693,7 @@ namespace Minigames.DivingForPictures
|
|||||||
Logging.Debug("[ObstacleSpawner] Started obstacle monitoring coroutine");
|
Logging.Debug("[ObstacleSpawner] Started obstacle monitoring coroutine");
|
||||||
|
|
||||||
// This coroutine now just monitors obstacles, not moves them
|
// This coroutine now just monitors obstacles, not moves them
|
||||||
while (enabled && gameObject.activeInHierarchy && !_isPaused)
|
while (enabled && gameObject.activeInHierarchy && !GameManager.Instance.IsPaused)
|
||||||
{
|
{
|
||||||
// Clean up any null references in the active obstacles list
|
// Clean up any null references in the active obstacles list
|
||||||
_activeObstacles.RemoveAll(obstacle => obstacle == null);
|
_activeObstacles.RemoveAll(obstacle => obstacle == null);
|
||||||
@@ -729,7 +715,7 @@ namespace Minigames.DivingForPictures
|
|||||||
const float checkInterval = 0.5f; // Check every half second
|
const float checkInterval = 0.5f; // Check every half second
|
||||||
Logging.Debug("[ObstacleSpawner] Started despawn coroutine with interval: " + checkInterval);
|
Logging.Debug("[ObstacleSpawner] Started despawn coroutine with interval: " + checkInterval);
|
||||||
|
|
||||||
while (enabled && gameObject.activeInHierarchy && !_isPaused)
|
while (enabled && gameObject.activeInHierarchy && !GameManager.Instance.IsPaused)
|
||||||
{
|
{
|
||||||
// Calculate screen bounds for despawning
|
// Calculate screen bounds for despawning
|
||||||
float despawnBuffer = 2f; // Extra buffer beyond screen edges
|
float despawnBuffer = 2f; // Extra buffer beyond screen edges
|
||||||
|
|||||||
@@ -18,26 +18,26 @@ namespace Minigames.DivingForPictures.Player
|
|||||||
[SerializeField] private EdgeAnchor edgeAnchor;
|
[SerializeField] private EdgeAnchor edgeAnchor;
|
||||||
|
|
||||||
// Settings reference
|
// Settings reference
|
||||||
private IDivingMinigameSettings settings;
|
private IDivingMinigameSettings _settings;
|
||||||
|
|
||||||
private float targetFingerX;
|
private float _targetFingerX;
|
||||||
private bool isTouchActive;
|
private bool _isTouchActive;
|
||||||
private float originY;
|
private float _originY;
|
||||||
|
|
||||||
// Tap impulse system variables
|
// Tap impulse system variables
|
||||||
private float tapImpulseStrength = 0f;
|
private float _tapImpulseStrength = 0f;
|
||||||
private float tapDirection = 0f;
|
private float _tapDirection = 0f;
|
||||||
|
|
||||||
// Initialization flag
|
// Initialization flag
|
||||||
private bool isInitialized = false;
|
private bool _isInitialized = false;
|
||||||
|
|
||||||
void Awake()
|
void Awake()
|
||||||
{
|
{
|
||||||
originY = transform.position.y;
|
_originY = transform.position.y;
|
||||||
|
|
||||||
// Get settings from GameManager
|
// Get settings from GameManager
|
||||||
settings = GameManager.GetSettingsObject<IDivingMinigameSettings>();
|
_settings = GameManager.GetSettingsObject<IDivingMinigameSettings>();
|
||||||
if (settings == null)
|
if (_settings == null)
|
||||||
{
|
{
|
||||||
Debug.LogError("[PlayerController] Failed to load diving minigame settings!");
|
Debug.LogError("[PlayerController] Failed to load diving minigame settings!");
|
||||||
}
|
}
|
||||||
@@ -49,8 +49,8 @@ namespace Minigames.DivingForPictures.Player
|
|||||||
DivingGameManager.Instance.RegisterPausableComponent(this);
|
DivingGameManager.Instance.RegisterPausableComponent(this);
|
||||||
|
|
||||||
// Initialize target to current position
|
// Initialize target to current position
|
||||||
targetFingerX = transform.position.x;
|
_targetFingerX = transform.position.x;
|
||||||
isTouchActive = false;
|
_isTouchActive = false;
|
||||||
|
|
||||||
// Try to find edge anchor if not assigned
|
// Try to find edge anchor if not assigned
|
||||||
if (edgeAnchor == null)
|
if (edgeAnchor == null)
|
||||||
@@ -100,12 +100,12 @@ namespace Minigames.DivingForPictures.Player
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void Initialize()
|
private void Initialize()
|
||||||
{
|
{
|
||||||
if (isInitialized) return;
|
if (_isInitialized) return;
|
||||||
|
|
||||||
// Register as default consumer for input
|
// Register as default consumer for input
|
||||||
InputManager.Instance?.SetDefaultConsumer(this);
|
InputManager.Instance?.SetDefaultConsumer(this);
|
||||||
|
|
||||||
isInitialized = true;
|
_isInitialized = true;
|
||||||
Logging.Debug("[PlayerController] Initialized");
|
Logging.Debug("[PlayerController] Initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,19 +130,19 @@ namespace Minigames.DivingForPictures.Player
|
|||||||
public void OnTap(Vector2 worldPosition)
|
public void OnTap(Vector2 worldPosition)
|
||||||
{
|
{
|
||||||
// Ignore input when paused
|
// Ignore input when paused
|
||||||
if (isPaused) return;
|
if (GameManager.Instance.IsPaused) return;
|
||||||
|
|
||||||
// Logging.Debug($"[EndlessDescenderController] OnTap at {worldPosition}");
|
// Logging.Debug($"[EndlessDescenderController] OnTap at {worldPosition}");
|
||||||
float targetX = Mathf.Clamp(worldPosition.x, settings.ClampXMin, settings.ClampXMax);
|
float targetX = Mathf.Clamp(worldPosition.x, _settings.ClampXMin, _settings.ClampXMax);
|
||||||
|
|
||||||
// Calculate tap direction (+1 for right, -1 for left)
|
// Calculate tap direction (+1 for right, -1 for left)
|
||||||
tapDirection = Mathf.Sign(targetX - transform.position.x);
|
_tapDirection = Mathf.Sign(targetX - transform.position.x);
|
||||||
|
|
||||||
// Set impulse strength to full
|
// Set impulse strength to full
|
||||||
tapImpulseStrength = 1.0f;
|
_tapImpulseStrength = 1.0f;
|
||||||
|
|
||||||
// Store target X for animation purposes
|
// Store target X for animation purposes
|
||||||
targetFingerX = targetX;
|
_targetFingerX = targetX;
|
||||||
|
|
||||||
// Do not set _isTouchActive for taps anymore
|
// Do not set _isTouchActive for taps anymore
|
||||||
// _isTouchActive = true; - Removed to prevent continuous movement
|
// _isTouchActive = true; - Removed to prevent continuous movement
|
||||||
@@ -154,11 +154,11 @@ namespace Minigames.DivingForPictures.Player
|
|||||||
public void OnHoldStart(Vector2 worldPosition)
|
public void OnHoldStart(Vector2 worldPosition)
|
||||||
{
|
{
|
||||||
// Ignore input when paused
|
// Ignore input when paused
|
||||||
if (isPaused) return;
|
if (GameManager.Instance.IsPaused) return;
|
||||||
|
|
||||||
// Logging.Debug($"[EndlessDescenderController] OnHoldStart at {worldPosition}");
|
// Logging.Debug($"[EndlessDescenderController] OnHoldStart at {worldPosition}");
|
||||||
targetFingerX = Mathf.Clamp(worldPosition.x, settings.ClampXMin, settings.ClampXMax);
|
_targetFingerX = Mathf.Clamp(worldPosition.x, _settings.ClampXMin, _settings.ClampXMax);
|
||||||
isTouchActive = true;
|
_isTouchActive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -167,10 +167,10 @@ namespace Minigames.DivingForPictures.Player
|
|||||||
public void OnHoldMove(Vector2 worldPosition)
|
public void OnHoldMove(Vector2 worldPosition)
|
||||||
{
|
{
|
||||||
// Ignore input when paused
|
// Ignore input when paused
|
||||||
if (isPaused) return;
|
if (GameManager.Instance.IsPaused) return;
|
||||||
|
|
||||||
// Logging.Debug($"[EndlessDescenderController] OnHoldMove at {worldPosition}");
|
// Logging.Debug($"[EndlessDescenderController] OnHoldMove at {worldPosition}");
|
||||||
targetFingerX = Mathf.Clamp(worldPosition.x, settings.ClampXMin, settings.ClampXMax);
|
_targetFingerX = Mathf.Clamp(worldPosition.x, _settings.ClampXMin, _settings.ClampXMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -179,25 +179,25 @@ namespace Minigames.DivingForPictures.Player
|
|||||||
public void OnHoldEnd(Vector2 worldPosition)
|
public void OnHoldEnd(Vector2 worldPosition)
|
||||||
{
|
{
|
||||||
// Ignore input when paused
|
// Ignore input when paused
|
||||||
if (isPaused) return;
|
if (GameManager.Instance.IsPaused) return;
|
||||||
|
|
||||||
// Logging.Debug($"[EndlessDescenderController] OnHoldEnd at {worldPosition}");
|
// Logging.Debug($"[EndlessDescenderController] OnHoldEnd at {worldPosition}");
|
||||||
isTouchActive = false;
|
_isTouchActive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Update()
|
void Update()
|
||||||
{
|
{
|
||||||
// Skip movement processing if paused
|
// Skip movement processing if paused
|
||||||
if (isPaused) return;
|
if (GameManager.Instance.IsPaused) return;
|
||||||
|
|
||||||
// Handle hold movement
|
// Handle hold movement
|
||||||
if (isTouchActive)
|
if (_isTouchActive)
|
||||||
{
|
{
|
||||||
float currentX = transform.position.x;
|
float currentX = transform.position.x;
|
||||||
float lerpSpeed = settings.LerpSpeed;
|
float lerpSpeed = _settings.LerpSpeed;
|
||||||
float maxOffset = settings.MaxOffset;
|
float maxOffset = _settings.MaxOffset;
|
||||||
float exponent = settings.SpeedExponent;
|
float exponent = _settings.SpeedExponent;
|
||||||
float targetX = targetFingerX;
|
float targetX = _targetFingerX;
|
||||||
float offset = targetX - currentX;
|
float offset = targetX - currentX;
|
||||||
offset = Mathf.Clamp(offset, -maxOffset, maxOffset);
|
offset = Mathf.Clamp(offset, -maxOffset, maxOffset);
|
||||||
float absOffset = Mathf.Abs(offset);
|
float absOffset = Mathf.Abs(offset);
|
||||||
@@ -206,32 +206,32 @@ namespace Minigames.DivingForPictures.Player
|
|||||||
// Prevent overshooting
|
// Prevent overshooting
|
||||||
moveStep = Mathf.Clamp(moveStep, -absOffset, absOffset);
|
moveStep = Mathf.Clamp(moveStep, -absOffset, absOffset);
|
||||||
float newX = currentX + moveStep;
|
float newX = currentX + moveStep;
|
||||||
newX = Mathf.Clamp(newX, settings.ClampXMin, settings.ClampXMax);
|
newX = Mathf.Clamp(newX, _settings.ClampXMin, _settings.ClampXMax);
|
||||||
|
|
||||||
UpdatePosition(newX);
|
UpdatePosition(newX);
|
||||||
}
|
}
|
||||||
// Handle tap impulse movement
|
// Handle tap impulse movement
|
||||||
else if (tapImpulseStrength > 0)
|
else if (_tapImpulseStrength > 0)
|
||||||
{
|
{
|
||||||
float currentX = transform.position.x;
|
float currentX = transform.position.x;
|
||||||
float maxOffset = settings.MaxOffset;
|
float maxOffset = _settings.MaxOffset;
|
||||||
float lerpSpeed = settings.LerpSpeed;
|
float lerpSpeed = _settings.LerpSpeed;
|
||||||
|
|
||||||
// Calculate move distance based on impulse strength
|
// Calculate move distance based on impulse strength
|
||||||
float moveDistance = maxOffset * tapImpulseStrength * Time.deltaTime * lerpSpeed;
|
float moveDistance = maxOffset * _tapImpulseStrength * Time.deltaTime * lerpSpeed;
|
||||||
|
|
||||||
// Limit total movement from single tap
|
// Limit total movement from single tap
|
||||||
moveDistance = Mathf.Min(moveDistance, settings.TapMaxDistance * tapImpulseStrength);
|
moveDistance = Mathf.Min(moveDistance, _settings.TapMaxDistance * _tapImpulseStrength);
|
||||||
|
|
||||||
// Apply movement in tap direction
|
// Apply movement in tap direction
|
||||||
float newX = currentX + (moveDistance * tapDirection);
|
float newX = currentX + (moveDistance * _tapDirection);
|
||||||
newX = Mathf.Clamp(newX, settings.ClampXMin, settings.ClampXMax);
|
newX = Mathf.Clamp(newX, _settings.ClampXMin, _settings.ClampXMax);
|
||||||
|
|
||||||
// Reduce impulse strength over time
|
// Reduce impulse strength over time
|
||||||
tapImpulseStrength -= Time.deltaTime * settings.TapDecelerationRate;
|
_tapImpulseStrength -= Time.deltaTime * _settings.TapDecelerationRate;
|
||||||
if (tapImpulseStrength < 0.01f)
|
if (_tapImpulseStrength < 0.01f)
|
||||||
{
|
{
|
||||||
tapImpulseStrength = 0f;
|
_tapImpulseStrength = 0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdatePosition(newX);
|
UpdatePosition(newX);
|
||||||
@@ -243,7 +243,7 @@ namespace Minigames.DivingForPictures.Player
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void UpdatePosition(float newX)
|
private void UpdatePosition(float newX)
|
||||||
{
|
{
|
||||||
float newY = originY;
|
float newY = _originY;
|
||||||
// Add vertical offset from WobbleBehavior if present
|
// Add vertical offset from WobbleBehavior if present
|
||||||
WobbleBehavior wobble = GetComponent<WobbleBehavior>();
|
WobbleBehavior wobble = GetComponent<WobbleBehavior>();
|
||||||
if (wobble != null)
|
if (wobble != null)
|
||||||
@@ -258,7 +258,7 @@ namespace Minigames.DivingForPictures.Player
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void UpdateOriginY(float newOriginY)
|
public void UpdateOriginY(float newOriginY)
|
||||||
{
|
{
|
||||||
originY = newOriginY;
|
_originY = newOriginY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -267,7 +267,7 @@ namespace Minigames.DivingForPictures.Player
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void UpdateOriginYFromCurrentPosition()
|
private void UpdateOriginYFromCurrentPosition()
|
||||||
{
|
{
|
||||||
originY = transform.position.y;
|
_originY = transform.position.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -276,24 +276,19 @@ namespace Minigames.DivingForPictures.Player
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void UpdateOriginYFromAnchor()
|
private void UpdateOriginYFromAnchor()
|
||||||
{
|
{
|
||||||
originY = edgeAnchor.transform.position.y;
|
_originY = edgeAnchor.transform.position.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region IPausable Implementation
|
#region IPausable Implementation
|
||||||
private bool isPaused = false;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Pauses the player controller, blocking all input processing
|
/// Pauses the player controller, blocking all input processing
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Pause()
|
public void Pause()
|
||||||
{
|
{
|
||||||
if (isPaused) return;
|
|
||||||
|
|
||||||
isPaused = true;
|
|
||||||
|
|
||||||
// If we're being paused, stop any active touch and tap impulse
|
// If we're being paused, stop any active touch and tap impulse
|
||||||
isTouchActive = false;
|
_isTouchActive = false;
|
||||||
tapImpulseStrength = 0f;
|
_tapImpulseStrength = 0f;
|
||||||
|
|
||||||
Logging.Debug("[PlayerController] Paused");
|
Logging.Debug("[PlayerController] Paused");
|
||||||
}
|
}
|
||||||
@@ -303,16 +298,8 @@ namespace Minigames.DivingForPictures.Player
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void DoResume()
|
public void DoResume()
|
||||||
{
|
{
|
||||||
if (!isPaused) return;
|
|
||||||
|
|
||||||
isPaused = false;
|
|
||||||
Logging.Debug("[PlayerController] Resumed");
|
Logging.Debug("[PlayerController] Resumed");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns whether the player controller is currently paused
|
|
||||||
/// </summary>
|
|
||||||
public bool IsPaused => isPaused;
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using AppleHills.Core.Settings;
|
using AppleHills.Core.Settings;
|
||||||
|
using Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a wobble (rocking and vertical movement) effect to the object, based on speed and time.
|
/// Adds a wobble (rocking and vertical movement) effect to the object, based on speed and time.
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
using System;
|
using System.Collections;
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Events;
|
using UnityEngine.Events;
|
||||||
using UnityEngine.Serialization;
|
using UnityEngine.Serialization;
|
||||||
using Pooling;
|
|
||||||
using AppleHills.Core.Settings;
|
using AppleHills.Core.Settings;
|
||||||
using Utils;
|
using Utils;
|
||||||
using AppleHills.Core.Interfaces;
|
using AppleHills.Core.Interfaces;
|
||||||
@@ -113,12 +111,6 @@ namespace Minigames.DivingForPictures
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pause state
|
|
||||||
private bool _isPaused = false;
|
|
||||||
|
|
||||||
// IPausable implementation
|
|
||||||
public bool IsPaused => _isPaused;
|
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
_mainCamera = UnityEngine.Camera.main;
|
_mainCamera = UnityEngine.Camera.main;
|
||||||
@@ -193,10 +185,6 @@ namespace Minigames.DivingForPictures
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Pause()
|
public void Pause()
|
||||||
{
|
{
|
||||||
if (_isPaused) return; // Already paused
|
|
||||||
|
|
||||||
_isPaused = true;
|
|
||||||
|
|
||||||
// Stop all active coroutines but save their references
|
// Stop all active coroutines but save their references
|
||||||
if (_movementCoroutine != null)
|
if (_movementCoroutine != null)
|
||||||
{
|
{
|
||||||
@@ -230,10 +218,6 @@ namespace Minigames.DivingForPictures
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void DoResume()
|
public void DoResume()
|
||||||
{
|
{
|
||||||
if (!_isPaused) return; // Already running
|
|
||||||
|
|
||||||
_isPaused = false;
|
|
||||||
|
|
||||||
// Restart all necessary coroutines
|
// Restart all necessary coroutines
|
||||||
StartMovementCoroutine();
|
StartMovementCoroutine();
|
||||||
StartTileDestructionCoroutine();
|
StartTileDestructionCoroutine();
|
||||||
@@ -500,7 +484,7 @@ namespace Minigames.DivingForPictures
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void StartMovementCoroutine()
|
private void StartMovementCoroutine()
|
||||||
{
|
{
|
||||||
if (_movementCoroutine == null && !_isPaused)
|
if (_movementCoroutine == null && !GameManager.Instance.IsPaused)
|
||||||
{
|
{
|
||||||
_movementCoroutine = StartCoroutine(MoveActiveTilesRoutine());
|
_movementCoroutine = StartCoroutine(MoveActiveTilesRoutine());
|
||||||
}
|
}
|
||||||
@@ -513,7 +497,7 @@ namespace Minigames.DivingForPictures
|
|||||||
{
|
{
|
||||||
Logging.Debug($"[TrenchTileSpawner] Started movement coroutine with normalized speed: {_baseMoveSpeed:F3}");
|
Logging.Debug($"[TrenchTileSpawner] Started movement coroutine with normalized speed: {_baseMoveSpeed:F3}");
|
||||||
|
|
||||||
while (enabled && gameObject.activeInHierarchy && !_isPaused)
|
while (enabled && gameObject.activeInHierarchy && !GameManager.Instance.IsPaused)
|
||||||
{
|
{
|
||||||
// Skip if no active tiles
|
// Skip if no active tiles
|
||||||
if (_activeTiles.Count == 0)
|
if (_activeTiles.Count == 0)
|
||||||
@@ -554,7 +538,7 @@ namespace Minigames.DivingForPictures
|
|||||||
const float checkInterval = 1.0f; // Check once per second
|
const float checkInterval = 1.0f; // Check once per second
|
||||||
Logging.Debug($"[TrenchTileSpawner] Started speed ramping coroutine with interval: {checkInterval}s");
|
Logging.Debug($"[TrenchTileSpawner] Started speed ramping coroutine with interval: {checkInterval}s");
|
||||||
|
|
||||||
while (enabled && gameObject.activeInHierarchy && !_isPaused)
|
while (enabled && gameObject.activeInHierarchy && !GameManager.Instance.IsPaused)
|
||||||
{
|
{
|
||||||
// Increase the base move speed up to the maximum
|
// Increase the base move speed up to the maximum
|
||||||
_baseMoveSpeed = Mathf.Min(_baseMoveSpeed + _settings.SpeedUpFactor, _settings.MaxNormalizedMoveSpeed);
|
_baseMoveSpeed = Mathf.Min(_baseMoveSpeed + _settings.SpeedUpFactor, _settings.MaxNormalizedMoveSpeed);
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ namespace Minigames.DivingForPictures.Utilities
|
|||||||
{
|
{
|
||||||
[SerializeField] private WobbleBehavior wobbleReference;
|
[SerializeField] private WobbleBehavior wobbleReference;
|
||||||
|
|
||||||
private bool isPaused = false;
|
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
DivingGameManager.Instance.RegisterPausableComponent(this);
|
DivingGameManager.Instance.RegisterPausableComponent(this);
|
||||||
@@ -17,15 +15,11 @@ namespace Minigames.DivingForPictures.Utilities
|
|||||||
public void Pause()
|
public void Pause()
|
||||||
{
|
{
|
||||||
wobbleReference.enabled = false;
|
wobbleReference.enabled = false;
|
||||||
isPaused = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DoResume()
|
public void DoResume()
|
||||||
{
|
{
|
||||||
wobbleReference.enabled = true;
|
wobbleReference.enabled = true;
|
||||||
isPaused = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsPaused => isPaused;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ namespace Minigames.DivingForPictures.Utilities
|
|||||||
[SerializeField] private RockFollower rockReference;
|
[SerializeField] private RockFollower rockReference;
|
||||||
[SerializeField] private WobbleBehavior rockWobbleReference;
|
[SerializeField] private WobbleBehavior rockWobbleReference;
|
||||||
|
|
||||||
private bool isPaused = false;
|
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
DivingGameManager.Instance.RegisterPausableComponent(this);
|
DivingGameManager.Instance.RegisterPausableComponent(this);
|
||||||
@@ -19,16 +17,12 @@ namespace Minigames.DivingForPictures.Utilities
|
|||||||
{
|
{
|
||||||
rockReference.enabled = false;
|
rockReference.enabled = false;
|
||||||
rockWobbleReference.enabled = false;
|
rockWobbleReference.enabled = false;
|
||||||
isPaused = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DoResume()
|
public void DoResume()
|
||||||
{
|
{
|
||||||
rockReference.enabled = true;
|
rockReference.enabled = true;
|
||||||
rockWobbleReference.enabled = true;
|
rockWobbleReference.enabled = true;
|
||||||
isPaused = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsPaused => isPaused;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using Pathfinding;
|
|||||||
using UnityEngine.SceneManagement;
|
using UnityEngine.SceneManagement;
|
||||||
using Utils;
|
using Utils;
|
||||||
using AppleHills.Core.Settings;
|
using AppleHills.Core.Settings;
|
||||||
|
using Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Controls the follower character, including following the player, handling pickups, and managing held items.
|
/// Controls the follower character, including following the player, handling pickups, and managing held items.
|
||||||
|
|||||||
112
Assets/Scripts/UI/BlinkingCanvasGroup.cs
Normal file
112
Assets/Scripts/UI/BlinkingCanvasGroup.cs
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
using Pixelplacement;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace UI
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a CanvasGroup (if missing) and plays a continuous blinking tween on its alpha.
|
||||||
|
/// Attach to any GameObject to make it pulse/fade in and out.
|
||||||
|
/// </summary>
|
||||||
|
[DisallowMultipleComponent]
|
||||||
|
[RequireComponent(typeof(CanvasGroup))]
|
||||||
|
public class BlinkingCanvasGroup : MonoBehaviour
|
||||||
|
{
|
||||||
|
[Header("Blink Settings")] [Tooltip("Minimum alpha value during blink")] [Range(0f, 1f)]
|
||||||
|
public float minAlpha;
|
||||||
|
|
||||||
|
[Tooltip("Maximum alpha value during blink")] [Range(0f, 1f)]
|
||||||
|
public float maxAlpha = 1f;
|
||||||
|
|
||||||
|
[Tooltip("Duration of one leg (min->max or max->min)")]
|
||||||
|
public float legDuration = 0.5f;
|
||||||
|
|
||||||
|
[Tooltip("Delay before starting the blinking")]
|
||||||
|
public float startDelay;
|
||||||
|
|
||||||
|
[Tooltip("Whether the tween should obey Time.timeScale (false = unscaled)")]
|
||||||
|
public bool obeyTimescale;
|
||||||
|
|
||||||
|
[Tooltip("Optional animation curve for easing. Leave null for default ease in/out.")]
|
||||||
|
public AnimationCurve easeCurve;
|
||||||
|
|
||||||
|
// Internal
|
||||||
|
private CanvasGroup _canvasGroup;
|
||||||
|
private Pixelplacement.TweenSystem.TweenBase _activeTween;
|
||||||
|
|
||||||
|
void Awake()
|
||||||
|
{
|
||||||
|
// Ensure we have a CanvasGroup
|
||||||
|
_canvasGroup = GetComponent<CanvasGroup>();
|
||||||
|
if (_canvasGroup == null)
|
||||||
|
{
|
||||||
|
_canvasGroup = gameObject.AddComponent<CanvasGroup>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure starting alpha
|
||||||
|
_canvasGroup.alpha = minAlpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Start()
|
||||||
|
{
|
||||||
|
StartBlinking();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnEnable()
|
||||||
|
{
|
||||||
|
// If re-enabled, ensure tween is running
|
||||||
|
if (_activeTween == null)
|
||||||
|
StartBlinking();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDisable()
|
||||||
|
{
|
||||||
|
StopBlinking();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDestroy()
|
||||||
|
{
|
||||||
|
StopBlinking();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Start the continuous blinking tween.
|
||||||
|
/// </summary>
|
||||||
|
public void StartBlinking()
|
||||||
|
{
|
||||||
|
StopBlinking();
|
||||||
|
|
||||||
|
if (_canvasGroup == null) return;
|
||||||
|
|
||||||
|
// Use PingPong-like behavior by chaining two opposite legs with LoopType.Loop
|
||||||
|
// Simpler: Tween.CanvasGroupAlpha has an overload that sets startAlpha then end.
|
||||||
|
// We'll tween min->max then set LoopType.PingPong if available. The API supports LoopType.PingPong.
|
||||||
|
|
||||||
|
// Start from minAlpha to maxAlpha
|
||||||
|
_canvasGroup.alpha = minAlpha;
|
||||||
|
|
||||||
|
// Use the Tween.Value overload for float with obeyTimescale parameter
|
||||||
|
_activeTween = Tween.Value(minAlpha, maxAlpha, v => _canvasGroup.alpha = v, legDuration, startDelay,
|
||||||
|
easeCurve ?? Tween.EaseInOut, Tween.LoopType.PingPong, null, null, obeyTimescale);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stops the blinking tween if running.
|
||||||
|
/// </summary>
|
||||||
|
public void StopBlinking()
|
||||||
|
{
|
||||||
|
if (_activeTween != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_activeTween.Cancel();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Some versions of the tween API may not expose Cancel; ignore safely.
|
||||||
|
}
|
||||||
|
|
||||||
|
_activeTween = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3
Assets/Scripts/UI/BlinkingCanvasGroup.cs.meta
Normal file
3
Assets/Scripts/UI/BlinkingCanvasGroup.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b75de64fb2fd4ff0b869bf469e2becea
|
||||||
|
timeCreated: 1761299308
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace UI.CardSystem
|
|
||||||
{
|
|
||||||
public class BackpackInput : MonoBehaviour, ITouchInputConsumer
|
|
||||||
{
|
|
||||||
// Start is called once before the first execution of Update after the MonoBehaviour is created
|
|
||||||
void Start()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update is called once per frame
|
|
||||||
void Update()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnTap(Vector2 position)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnHoldStart(Vector2 position)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnHoldMove(Vector2 position)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnHoldEnd(Vector2 position)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: e7ea50a695c58944799b4f27a9014301
|
|
||||||
@@ -2,7 +2,6 @@
|
|||||||
using Bootstrap;
|
using Bootstrap;
|
||||||
using Core;
|
using Core;
|
||||||
using Data.CardSystem;
|
using Data.CardSystem;
|
||||||
using Input;
|
|
||||||
using Pixelplacement;
|
using Pixelplacement;
|
||||||
using UI.Core;
|
using UI.Core;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@@ -33,8 +32,7 @@ namespace UI.CardSystem
|
|||||||
public GameObject BackpackIcon => backpackIcon;
|
public GameObject BackpackIcon => backpackIcon;
|
||||||
private UIPageController PageController => UIPageController.Instance;
|
private UIPageController PageController => UIPageController.Instance;
|
||||||
private CardSystemManager _cardManager;
|
private CardSystemManager _cardManager;
|
||||||
private bool _isInitialized = false;
|
private bool _hasUnseenCards;
|
||||||
private bool _hasUnseenCards = false;
|
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
@@ -44,9 +42,6 @@ namespace UI.CardSystem
|
|||||||
backpackButton.onClick.AddListener(OnBackpackButtonClicked);
|
backpackButton.onClick.AddListener(OnBackpackButtonClicked);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initially show only the backpack icon
|
|
||||||
ShowOnlyBackpackIcon();
|
|
||||||
|
|
||||||
// Hide notification dot initially
|
// Hide notification dot initially
|
||||||
if (boosterNotificationDot != null)
|
if (boosterNotificationDot != null)
|
||||||
boosterNotificationDot.gameObject.SetActive(false);
|
boosterNotificationDot.gameObject.SetActive(false);
|
||||||
@@ -57,8 +52,18 @@ namespace UI.CardSystem
|
|||||||
|
|
||||||
private void InitializePostBoot()
|
private void InitializePostBoot()
|
||||||
{
|
{
|
||||||
|
// Initially show only the backpack icon
|
||||||
|
ShowOnlyBackpackIcon();
|
||||||
|
|
||||||
// Initialize pages and hide them
|
// Initialize pages and hide them
|
||||||
InitializePages();
|
InitializePages();
|
||||||
|
|
||||||
|
// React to global UI hide/show events (top-page only) by toggling this GameObject
|
||||||
|
if (UIPageController.Instance != null)
|
||||||
|
{
|
||||||
|
UIPageController.Instance.OnAllUIHidden += HandleAllUIHidden;
|
||||||
|
UIPageController.Instance.OnAllUIShown += HandleAllUIShown;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
@@ -77,8 +82,6 @@ namespace UI.CardSystem
|
|||||||
// Initialize UI with current values
|
// Initialize UI with current values
|
||||||
UpdateBoosterCount(_cardManager.GetBoosterPackCount());
|
UpdateBoosterCount(_cardManager.GetBoosterPackCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
_isInitialized = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDestroy()
|
private void OnDestroy()
|
||||||
@@ -103,6 +106,13 @@ namespace UI.CardSystem
|
|||||||
{
|
{
|
||||||
PageController.OnPageChanged -= OnPageChanged;
|
PageController.OnPageChanged -= OnPageChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unsubscribe from global UI hide/show events
|
||||||
|
if (UIPageController.Instance != null)
|
||||||
|
{
|
||||||
|
UIPageController.Instance.OnAllUIHidden -= HandleAllUIHidden;
|
||||||
|
UIPageController.Instance.OnAllUIShown -= HandleAllUIShown;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -142,10 +152,6 @@ namespace UI.CardSystem
|
|||||||
if (notificationSound != null)
|
if (notificationSound != null)
|
||||||
notificationSound.Play();
|
notificationSound.Play();
|
||||||
|
|
||||||
// Eat input so the characters don't walk around
|
|
||||||
var backpackInput = backpackIcon.gameObject.GetComponentInParent<BackpackInput>();
|
|
||||||
InputManager.Instance.RegisterOverrideConsumer(backpackInput);
|
|
||||||
|
|
||||||
PageController.PushPage(mainMenuPage);
|
PageController.PushPage(mainMenuPage);
|
||||||
|
|
||||||
// Clear notification for unseen cards when opening menu
|
// Clear notification for unseen cards when opening menu
|
||||||
@@ -159,6 +165,8 @@ namespace UI.CardSystem
|
|||||||
{
|
{
|
||||||
backpackButton.gameObject.SetActive(false);
|
backpackButton.gameObject.SetActive(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GameManager.Instance.RequestPause(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -170,8 +178,7 @@ namespace UI.CardSystem
|
|||||||
if (newPage == null)
|
if (newPage == null)
|
||||||
{
|
{
|
||||||
ShowOnlyBackpackIcon();
|
ShowOnlyBackpackIcon();
|
||||||
var backpackInput = backpackIcon.gameObject.GetComponentInParent<BackpackInput>();
|
GameManager.Instance.ReleasePause(this);
|
||||||
InputManager.Instance.UnregisterOverrideConsumer(backpackInput);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -315,5 +322,19 @@ namespace UI.CardSystem
|
|||||||
// Just log the upgrade event without showing a notification
|
// Just log the upgrade event without showing a notification
|
||||||
Logging.Debug($"[CardAlbumUI] Card upgraded: {card.Name} to {card.Rarity}");
|
Logging.Debug($"[CardAlbumUI] Card upgraded: {card.Name} to {card.Rarity}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handlers for UI controller hide/show events — toggle this GameObject active state
|
||||||
|
private void HandleAllUIHidden()
|
||||||
|
{
|
||||||
|
// Ensure UI returns to backpack-only state before deactivating so we don't leave the game paused
|
||||||
|
ShowOnlyBackpackIcon();
|
||||||
|
backpackButton.gameObject.SetActive(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleAllUIShown()
|
||||||
|
{
|
||||||
|
backpackButton.gameObject.SetActive(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,10 @@ namespace UI.Core
|
|||||||
// Event fired when the page stack changes
|
// Event fired when the page stack changes
|
||||||
public event Action<UIPage> OnPageChanged;
|
public event Action<UIPage> OnPageChanged;
|
||||||
|
|
||||||
|
// Events fired when the controller hides or shows all UI pages
|
||||||
|
public event Action OnAllUIHidden;
|
||||||
|
public event Action OnAllUIShown;
|
||||||
|
|
||||||
private PlayerInput _playerInput;
|
private PlayerInput _playerInput;
|
||||||
private InputAction _cancelAction;
|
private InputAction _cancelAction;
|
||||||
|
|
||||||
@@ -141,5 +145,39 @@ namespace UI.Core
|
|||||||
OnPageChanged?.Invoke(null);
|
OnPageChanged?.Invoke(null);
|
||||||
Logging.Debug("[UIPageController] Cleared page stack");
|
Logging.Debug("[UIPageController] Cleared page stack");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Hide all currently stacked UI pages by calling TransitionOut on each.
|
||||||
|
/// This does not modify the page stack; it simply asks pages to transition out
|
||||||
|
/// so UI elements can be hidden. Subscribers can react to <see cref="OnAllUIHidden"/>.
|
||||||
|
/// </summary>
|
||||||
|
public void HideAllUI()
|
||||||
|
{
|
||||||
|
// Only transition out the top (active) page — maintains stack semantics.
|
||||||
|
var current = CurrentPage;
|
||||||
|
if (current != null)
|
||||||
|
{
|
||||||
|
current.TransitionOut();
|
||||||
|
}
|
||||||
|
|
||||||
|
OnAllUIHidden?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Show all currently stacked UI pages by calling TransitionIn on each from bottom to top.
|
||||||
|
/// This does not modify the page stack; it asks pages to transition in so UI elements become visible.
|
||||||
|
/// Subscribers can react to <see cref="OnAllUIShown"/>.
|
||||||
|
/// </summary>
|
||||||
|
public void ShowAllUI()
|
||||||
|
{
|
||||||
|
// Only transition in the top (active) page — maintains stack semantics.
|
||||||
|
var current = CurrentPage;
|
||||||
|
if (current != null)
|
||||||
|
{
|
||||||
|
current.TransitionIn();
|
||||||
|
}
|
||||||
|
|
||||||
|
OnAllUIShown?.Invoke();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using System;
|
|||||||
using Core;
|
using Core;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.SceneManagement;
|
using UnityEngine.SceneManagement;
|
||||||
using Input;
|
|
||||||
using Bootstrap;
|
using Bootstrap;
|
||||||
using UI.Core;
|
using UI.Core;
|
||||||
using Pixelplacement;
|
using Pixelplacement;
|
||||||
@@ -12,7 +11,6 @@ namespace UI
|
|||||||
public class PauseMenu : UIPage
|
public class PauseMenu : UIPage
|
||||||
{
|
{
|
||||||
private static PauseMenu _instance;
|
private static PauseMenu _instance;
|
||||||
private static bool _isQuitting;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Singleton instance of the PauseMenu. No longer creates an instance if one doesn't exist.
|
/// Singleton instance of the PauseMenu. No longer creates an instance if one doesn't exist.
|
||||||
@@ -24,15 +22,6 @@ namespace UI
|
|||||||
[SerializeField] private GameObject pauseButton;
|
[SerializeField] private GameObject pauseButton;
|
||||||
[SerializeField] private CanvasGroup canvasGroup;
|
[SerializeField] private CanvasGroup canvasGroup;
|
||||||
|
|
||||||
public event Action OnGamePaused;
|
|
||||||
public event Action OnGameResumed;
|
|
||||||
|
|
||||||
private bool _isPaused = false;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns whether the game is currently paused
|
|
||||||
/// </summary>
|
|
||||||
public bool IsPaused => _isPaused;
|
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
@@ -57,6 +46,13 @@ namespace UI
|
|||||||
// Subscribe to scene loaded events
|
// Subscribe to scene loaded events
|
||||||
SceneManagerService.Instance.SceneLoadCompleted += SetPauseMenuByLevel;
|
SceneManagerService.Instance.SceneLoadCompleted += SetPauseMenuByLevel;
|
||||||
|
|
||||||
|
// Also react to global UI hide/show events from the page controller
|
||||||
|
if (UIPageController.Instance != null)
|
||||||
|
{
|
||||||
|
UIPageController.Instance.OnAllUIHidden += HandleAllUIHidden;
|
||||||
|
UIPageController.Instance.OnAllUIShown += HandleAllUIShown;
|
||||||
|
}
|
||||||
|
|
||||||
// SceneManagerService subscription moved to InitializePostBoot
|
// SceneManagerService subscription moved to InitializePostBoot
|
||||||
|
|
||||||
// Set initial state based on current scene
|
// Set initial state based on current scene
|
||||||
@@ -72,11 +68,11 @@ namespace UI
|
|||||||
{
|
{
|
||||||
SceneManagerService.Instance.SceneLoadCompleted -= SetPauseMenuByLevel;
|
SceneManagerService.Instance.SceneLoadCompleted -= SetPauseMenuByLevel;
|
||||||
}
|
}
|
||||||
}
|
if (UIPageController.Instance != null)
|
||||||
|
|
||||||
void OnApplicationQuit()
|
|
||||||
{
|
{
|
||||||
_isQuitting = true;
|
UIPageController.Instance.OnAllUIHidden -= HandleAllUIHidden;
|
||||||
|
UIPageController.Instance.OnAllUIShown -= HandleAllUIShown;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -85,7 +81,7 @@ namespace UI
|
|||||||
/// <param name="levelName">The name of the level/scene</param>
|
/// <param name="levelName">The name of the level/scene</param>
|
||||||
public void SetPauseMenuByLevel(string levelName)
|
public void SetPauseMenuByLevel(string levelName)
|
||||||
{
|
{
|
||||||
HidePauseMenu(false);
|
HidePauseMenu();
|
||||||
// TODO: Implement level-based pause menu visibility logic if needed
|
// TODO: Implement level-based pause menu visibility logic if needed
|
||||||
/*if (string.IsNullOrEmpty(levelName))
|
/*if (string.IsNullOrEmpty(levelName))
|
||||||
return;
|
return;
|
||||||
@@ -103,7 +99,6 @@ namespace UI
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void ShowPauseMenu()
|
public void ShowPauseMenu()
|
||||||
{
|
{
|
||||||
if (_isPaused) return;
|
|
||||||
if (UIPageController.Instance != null)
|
if (UIPageController.Instance != null)
|
||||||
{
|
{
|
||||||
UIPageController.Instance.PushPage(this);
|
UIPageController.Instance.PushPage(this);
|
||||||
@@ -128,9 +123,9 @@ namespace UI
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Hides the pause menu and shows the pause button. Sets input mode to Game.
|
/// Hides the pause menu and shows the pause button. Sets input mode to Game.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void HidePauseMenu(bool resetInput = true)
|
public void HidePauseMenu()
|
||||||
{
|
{
|
||||||
if (!_isPaused)
|
if (!GameManager.Instance.IsPaused)
|
||||||
{
|
{
|
||||||
// Ensure UI is hidden if somehow active without state
|
// Ensure UI is hidden if somehow active without state
|
||||||
if (pauseMenuPanel != null) pauseMenuPanel.SetActive(false);
|
if (pauseMenuPanel != null) pauseMenuPanel.SetActive(false);
|
||||||
@@ -148,7 +143,6 @@ namespace UI
|
|||||||
pauseMenuPanel.SetActive(false);
|
pauseMenuPanel.SetActive(false);
|
||||||
if (pauseButton != null)
|
if (pauseButton != null)
|
||||||
pauseButton.SetActive(true);
|
pauseButton.SetActive(true);
|
||||||
EndPauseSideEffects(resetInput);
|
|
||||||
if (canvasGroup != null)
|
if (canvasGroup != null)
|
||||||
{
|
{
|
||||||
canvasGroup.alpha = 0f;
|
canvasGroup.alpha = 0f;
|
||||||
@@ -159,29 +153,31 @@ namespace UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void HidePauseMenuAndResumeGame()
|
||||||
|
{
|
||||||
|
HidePauseMenu();
|
||||||
|
EndPauseSideEffects();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resumes the game by hiding the pause menu.
|
/// Resumes the game by hiding the pause menu.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ResumeGame()
|
public void ResumeGame()
|
||||||
{
|
{
|
||||||
HidePauseMenu();
|
HidePauseMenuAndResumeGame();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BeginPauseSideEffects()
|
private void BeginPauseSideEffects()
|
||||||
{
|
{
|
||||||
_isPaused = true;
|
|
||||||
if (pauseButton != null) pauseButton.SetActive(false);
|
if (pauseButton != null) pauseButton.SetActive(false);
|
||||||
InputManager.Instance.SetInputMode(InputMode.UI);
|
GameManager.Instance.RequestPause(this);
|
||||||
OnGamePaused?.Invoke();
|
|
||||||
Logging.Debug("[PauseMenu] Game Paused");
|
Logging.Debug("[PauseMenu] Game Paused");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EndPauseSideEffects(bool invokeEvent)
|
private void EndPauseSideEffects()
|
||||||
{
|
{
|
||||||
_isPaused = false;
|
|
||||||
if (pauseButton != null) pauseButton.SetActive(true);
|
if (pauseButton != null) pauseButton.SetActive(true);
|
||||||
InputManager.Instance.SetInputMode(InputMode.GameAndUI);
|
GameManager.Instance.ReleasePause(this);
|
||||||
if (invokeEvent) OnGameResumed?.Invoke();
|
|
||||||
Logging.Debug("[PauseMenu] Game Resumed");
|
Logging.Debug("[PauseMenu] Game Resumed");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,6 +185,8 @@ namespace UI
|
|||||||
{
|
{
|
||||||
// Ensure the panel root is active
|
// Ensure the panel root is active
|
||||||
if (pauseMenuPanel != null) pauseMenuPanel.SetActive(true);
|
if (pauseMenuPanel != null) pauseMenuPanel.SetActive(true);
|
||||||
|
// Pause side effects should run immediately (hide button, set input mode, etc.).
|
||||||
|
// The tween itself must run in unscaled time so it still animates while the game is paused.
|
||||||
BeginPauseSideEffects();
|
BeginPauseSideEffects();
|
||||||
|
|
||||||
if (canvasGroup != null)
|
if (canvasGroup != null)
|
||||||
@@ -196,7 +194,16 @@ namespace UI
|
|||||||
canvasGroup.interactable = true;
|
canvasGroup.interactable = true;
|
||||||
canvasGroup.blocksRaycasts = true;
|
canvasGroup.blocksRaycasts = true;
|
||||||
canvasGroup.alpha = 0f;
|
canvasGroup.alpha = 0f;
|
||||||
Tween.Value(0f, 1f, v => canvasGroup.alpha = v, transitionDuration, 0f, Tween.EaseInOut, Tween.LoopType.None, null, onComplete);
|
// pass obeyTimescale = false so this tween runs even when Time.timeScale == 0
|
||||||
|
Tween.Value(0f, 1f, (v) =>
|
||||||
|
{
|
||||||
|
Logging.Debug($"[PauseMenu] Tweening pause menu alpha: {v}");
|
||||||
|
canvasGroup.alpha = v;
|
||||||
|
}, transitionDuration, 0f, Tween.EaseInOut, Tween.LoopType.None, null, () =>
|
||||||
|
{
|
||||||
|
Logging.Debug("[PauseMenu] Finished tweening pause menu in.");
|
||||||
|
onComplete?.Invoke();
|
||||||
|
}, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -210,16 +217,17 @@ namespace UI
|
|||||||
{
|
{
|
||||||
canvasGroup.interactable = false;
|
canvasGroup.interactable = false;
|
||||||
canvasGroup.blocksRaycasts = false;
|
canvasGroup.blocksRaycasts = false;
|
||||||
|
// Run out-tween in unscaled time as well so the fade completes while paused.
|
||||||
Tween.Value(canvasGroup.alpha, 0f, v => canvasGroup.alpha = v, transitionDuration, 0f, Tween.EaseInOut, Tween.LoopType.None, null, () =>
|
Tween.Value(canvasGroup.alpha, 0f, v => canvasGroup.alpha = v, transitionDuration, 0f, Tween.EaseInOut, Tween.LoopType.None, null, () =>
|
||||||
{
|
{
|
||||||
EndPauseSideEffects(true);
|
EndPauseSideEffects();
|
||||||
if (pauseMenuPanel != null) pauseMenuPanel.SetActive(false);
|
if (pauseMenuPanel != null) pauseMenuPanel.SetActive(false);
|
||||||
onComplete?.Invoke();
|
onComplete?.Invoke();
|
||||||
});
|
}, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EndPauseSideEffects(true);
|
EndPauseSideEffects();
|
||||||
if (pauseMenuPanel != null) pauseMenuPanel.SetActive(false);
|
if (pauseMenuPanel != null) pauseMenuPanel.SetActive(false);
|
||||||
onComplete?.Invoke();
|
onComplete?.Invoke();
|
||||||
}
|
}
|
||||||
@@ -261,7 +269,7 @@ namespace UI
|
|||||||
public async void LoadLevel(int levelSelection)
|
public async void LoadLevel(int levelSelection)
|
||||||
{
|
{
|
||||||
// Hide the pause menu before loading a new level
|
// Hide the pause menu before loading a new level
|
||||||
HidePauseMenu();
|
HidePauseMenuAndResumeGame();
|
||||||
|
|
||||||
// Replace with the actual scene name as set in Build Settings
|
// Replace with the actual scene name as set in Build Settings
|
||||||
var progress = new Progress<float>(p => Logging.Debug($"Loading progress: {p * 100:F0}%"));
|
var progress = new Progress<float>(p => Logging.Debug($"Loading progress: {p * 100:F0}%"));
|
||||||
@@ -278,5 +286,42 @@ namespace UI
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handlers for UI controller hide/show events — make these safe with respect to transitions and pause state
|
||||||
|
private void HandleAllUIHidden()
|
||||||
|
{
|
||||||
|
var parent = transform.parent?.gameObject ?? gameObject;
|
||||||
|
|
||||||
|
// If we're currently transitioning, wait for the transition out to complete before deactivating
|
||||||
|
if (_isTransitioning)
|
||||||
|
{
|
||||||
|
Action handler = null;
|
||||||
|
handler = () =>
|
||||||
|
{
|
||||||
|
OnTransitionOutCompleted -= handler;
|
||||||
|
parent.SetActive(false);
|
||||||
|
};
|
||||||
|
OnTransitionOutCompleted += handler;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this page is visible, request a proper hide so transition/out side-effects run (e.g. releasing pause)
|
||||||
|
if (_isVisible)
|
||||||
|
{
|
||||||
|
HidePauseMenu();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise it's safe to immediately deactivate
|
||||||
|
parent.SetActive(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleAllUIShown()
|
||||||
|
{
|
||||||
|
var parent = transform.parent?.gameObject ?? gameObject;
|
||||||
|
|
||||||
|
// Just ensure the parent is active. Do not force pause or transitions here.
|
||||||
|
parent.SetActive(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,64 +1,86 @@
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Linq;
|
using Bootstrap;
|
||||||
using UnityEngine;
|
using Core;
|
||||||
using Pixelplacement;
|
|
||||||
using Minigames.DivingForPictures;
|
|
||||||
using Input;
|
using Input;
|
||||||
using UnityEngine.Events;
|
using Pixelplacement;
|
||||||
|
using UI.Core;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
public class DivingTutorial : MonoBehaviour, ITouchInputConsumer
|
namespace UI.Tutorial
|
||||||
{
|
{
|
||||||
private StateMachine stateMachine;
|
public class DivingTutorial : MonoBehaviour, ITouchInputConsumer
|
||||||
public DivingGameManager divingGameManager;
|
{
|
||||||
|
private StateMachine _stateMachine;
|
||||||
public bool playTutorial;
|
public bool playTutorial;
|
||||||
|
|
||||||
// gating for input until current state's animation finishes first loop
|
// gating for input until current state's animation finishes first loop
|
||||||
private bool canAcceptInput = false;
|
[SerializeField] private GameObject tapPrompt;
|
||||||
private Coroutine waitLoopCoroutine;
|
|
||||||
|
private bool _canAcceptInput;
|
||||||
|
private Coroutine _waitLoopCoroutine;
|
||||||
|
|
||||||
// Start is called once before the first execution of Update after the MonoBehaviour is created
|
// Start is called once before the first execution of Update after the MonoBehaviour is created
|
||||||
void Start()
|
void Start()
|
||||||
{
|
{
|
||||||
if (playTutorial == true)
|
BootCompletionService.RegisterInitAction(InitializeTutorial);
|
||||||
{
|
|
||||||
InitializeTutorial();
|
// Ensure prompt is hidden initially (even before tutorial initialization)
|
||||||
}
|
if (tapPrompt != null)
|
||||||
else { RemoveTutorial(); }
|
tapPrompt.SetActive(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializeTutorial()
|
void InitializeTutorial()
|
||||||
{
|
{
|
||||||
stateMachine = GetComponentInChildren<StateMachine>();
|
if (playTutorial)
|
||||||
divingGameManager.Pause();
|
{
|
||||||
|
// pause the game, hide UI, and register for input overrides
|
||||||
|
GameManager.Instance.RequestPause(this);
|
||||||
|
UIPageController.Instance.HideAllUI();
|
||||||
InputManager.Instance.RegisterOverrideConsumer(this);
|
InputManager.Instance.RegisterOverrideConsumer(this);
|
||||||
stateMachine.OnLastStateExited.AddListener(RemoveTutorial);
|
|
||||||
|
// Setup references
|
||||||
|
_stateMachine = GetComponentInChildren<StateMachine>();
|
||||||
|
_stateMachine.OnLastStateExited.AddListener(RemoveTutorial);
|
||||||
|
|
||||||
// prepare gating for the initial active state
|
// prepare gating for the initial active state
|
||||||
SetupInputGateForCurrentState();
|
SetupInputGateForCurrentState();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RemoveTutorial();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RemoveTutorial()
|
void RemoveTutorial()
|
||||||
{
|
{
|
||||||
Debug.Log("Remove me!");
|
Debug.Log("Remove me!");
|
||||||
if (waitLoopCoroutine != null)
|
if (_waitLoopCoroutine != null)
|
||||||
{
|
{
|
||||||
StopCoroutine(waitLoopCoroutine);
|
StopCoroutine(_waitLoopCoroutine);
|
||||||
waitLoopCoroutine = null;
|
_waitLoopCoroutine = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unpause, unregister input, and show UI
|
||||||
InputManager.Instance.UnregisterOverrideConsumer(this);
|
InputManager.Instance.UnregisterOverrideConsumer(this);
|
||||||
divingGameManager.DoResume();
|
UIPageController.Instance.ShowAllUI();
|
||||||
|
GameManager.Instance.ReleasePause(this);
|
||||||
|
|
||||||
|
// hide prompt if present
|
||||||
|
if (tapPrompt != null)
|
||||||
|
tapPrompt.SetActive(false);
|
||||||
|
|
||||||
Destroy(gameObject);
|
Destroy(gameObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnTap(Vector2 position)
|
public void OnTap(Vector2 position)
|
||||||
{
|
{
|
||||||
if (!canAcceptInput) return; // block taps until allowed
|
if (!_canAcceptInput) return; // block taps until allowed
|
||||||
|
|
||||||
// consume this tap and immediately block further taps
|
// consume this tap and immediately block further taps
|
||||||
canAcceptInput = false;
|
SetInputEnabled(false);
|
||||||
|
|
||||||
// move to next state
|
// move to next state
|
||||||
stateMachine.Next(true);
|
_stateMachine.Next(true);
|
||||||
|
|
||||||
// after the state changes, set up gating for the new active state's animation
|
// after the state changes, set up gating for the new active state's animation
|
||||||
SetupInputGateForCurrentState();
|
SetupInputGateForCurrentState();
|
||||||
@@ -66,27 +88,34 @@ public class DivingTutorial : MonoBehaviour, ITouchInputConsumer
|
|||||||
|
|
||||||
public void OnHoldStart(Vector2 position)
|
public void OnHoldStart(Vector2 position)
|
||||||
{
|
{
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnHoldMove(Vector2 position)
|
public void OnHoldMove(Vector2 position)
|
||||||
{
|
{
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnHoldEnd(Vector2 position)
|
public void OnHoldEnd(Vector2 position)
|
||||||
{
|
{
|
||||||
return;
|
}
|
||||||
|
|
||||||
|
// centralize enabling/disabling input and the tap prompt
|
||||||
|
private void SetInputEnabled(bool allow)
|
||||||
|
{
|
||||||
|
_canAcceptInput = allow;
|
||||||
|
if (tapPrompt != null)
|
||||||
|
{
|
||||||
|
tapPrompt.SetActive(allow);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetupInputGateForCurrentState()
|
private void SetupInputGateForCurrentState()
|
||||||
{
|
{
|
||||||
if (waitLoopCoroutine != null)
|
if (_waitLoopCoroutine != null)
|
||||||
{
|
{
|
||||||
StopCoroutine(waitLoopCoroutine);
|
StopCoroutine(_waitLoopCoroutine);
|
||||||
waitLoopCoroutine = null;
|
_waitLoopCoroutine = null;
|
||||||
}
|
}
|
||||||
waitLoopCoroutine = StartCoroutine(WaitForFirstLoopOnActiveState());
|
_waitLoopCoroutine = StartCoroutine(WaitForFirstLoopOnActiveState());
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerator WaitForFirstLoopOnActiveState()
|
private IEnumerator WaitForFirstLoopOnActiveState()
|
||||||
@@ -95,7 +124,7 @@ public class DivingTutorial : MonoBehaviour, ITouchInputConsumer
|
|||||||
yield return null;
|
yield return null;
|
||||||
|
|
||||||
// find the active child under the StateMachine (the current state)
|
// find the active child under the StateMachine (the current state)
|
||||||
Transform smTransform = stateMachine != null ? stateMachine.transform : transform;
|
Transform smTransform = _stateMachine != null ? _stateMachine.transform : transform;
|
||||||
Transform activeState = null;
|
Transform activeState = null;
|
||||||
for (int i = 0; i < smTransform.childCount; i++)
|
for (int i = 0; i < smTransform.childCount; i++)
|
||||||
{
|
{
|
||||||
@@ -110,7 +139,7 @@ public class DivingTutorial : MonoBehaviour, ITouchInputConsumer
|
|||||||
if (activeState == null)
|
if (activeState == null)
|
||||||
{
|
{
|
||||||
// if we can't find an active state, fail open: allow input
|
// if we can't find an active state, fail open: allow input
|
||||||
canAcceptInput = true;
|
SetInputEnabled(true);
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,7 +148,7 @@ public class DivingTutorial : MonoBehaviour, ITouchInputConsumer
|
|||||||
if (anim == null)
|
if (anim == null)
|
||||||
{
|
{
|
||||||
// no animation to wait for; allow input immediately
|
// no animation to wait for; allow input immediately
|
||||||
canAcceptInput = true;
|
SetInputEnabled(true);
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +173,7 @@ public class DivingTutorial : MonoBehaviour, ITouchInputConsumer
|
|||||||
if (observedState == null)
|
if (observedState == null)
|
||||||
{
|
{
|
||||||
// nothing to observe; allow input
|
// nothing to observe; allow input
|
||||||
canAcceptInput = true;
|
SetInputEnabled(true);
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,7 +198,8 @@ public class DivingTutorial : MonoBehaviour, ITouchInputConsumer
|
|||||||
yield return null;
|
yield return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
canAcceptInput = true;
|
SetInputEnabled(true);
|
||||||
waitLoopCoroutine = null;
|
_waitLoopCoroutine = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user