Add a pause menu, auto load via bootstrap and correctly show depending on the current scene

This commit is contained in:
Michal Pikulski
2025-09-25 12:02:18 +02:00
parent 74e65fdf42
commit 05753cc214
11 changed files with 3223 additions and 108 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@@ -0,0 +1,195 @@
fileFormatVersion: 2
guid: 0a391f68acfee1041a26723b1dafb73b
TextureImporter:
internalIDToNameTable:
- first:
213: 1108211999407853544
second: MenuIcon_PLACEHOLDER_0
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 2
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: iOS
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WindowsStoreApps
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites:
- serializedVersion: 2
name: MenuIcon_PLACEHOLDER_0
rect:
serializedVersion: 2
x: 9
y: 8
width: 239
height: 240
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
customData:
outline: []
physicsShape: []
tessellationDetail: -1
bones: []
spriteID: 8efc78021f8216f00800000000000000
internalID: 1108211999407853544
vertices: []
indices:
edges: []
weights: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable:
MenuIcon_PLACEHOLDER_0: 1108211999407853544
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -18,3 +18,4 @@ MonoBehaviour:
- {fileID: 458265635552197097, guid: a77d1e8b2fa8aa945a6f39b312536e0d, type: 3}
- {fileID: 552225285624929822, guid: e39992796d5459442be9967c77e27066, type: 3}
- {fileID: 7644433920135100480, guid: 12d242e44fe80ab44af852254b7cab0f, type: 3}
- {fileID: 1794231825201849485, guid: 6fb0d7fc6faad154b8c3e3cb7abb7c15, type: 3}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 6fb0d7fc6faad154b8c3e3cb7abb7c15
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1633,6 +1633,37 @@ SpriteRenderer:
m_CorrespondingSourceObject: {fileID: 7494677664706785084, guid: bf4b9d7045397f946b2125b1ad4a3fbd, type: 3}
m_PrefabInstance: {fileID: 1336824707}
m_PrefabAsset: {fileID: 0}
--- !u!1 &1668240410
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1668240411}
m_Layer: 0
m_Name: Buttons
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1668240411
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1668240410}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 898.1756, y: 720.9647, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1741016587
GameObject:
m_ObjectHideFlags: 0
@@ -2062,3 +2093,4 @@ SceneRoots:
- {fileID: 1234715653}
- {fileID: 1336824707}
- {fileID: 384576747}
- {fileID: 1668240411}

View File

@@ -438175,50 +438175,6 @@ Transform:
m_CorrespondingSourceObject: {fileID: 5145306031820616614, guid: fbbe1f4baf226904b96f839fe0c00181, type: 3}
m_PrefabInstance: {fileID: 1352048898}
m_PrefabAsset: {fileID: 0}
--- !u!1 &1360662869
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1360662870}
- component: {fileID: 1360662871}
m_Layer: 0
m_Name: TestObject
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1360662870
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1360662869}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0.45709, y: -0.24522, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1360662871
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1360662869}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d086a8fb5e4cfc047a52b859f91fb867, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!1001 &1363194738
PrefabInstance:
m_ObjectHideFlags: 0
@@ -445464,4 +445420,3 @@ SceneRoots:
- {fileID: 122256018}
- {fileID: 1101333109}
- {fileID: 4912039252317080710}
- {fileID: 1360662870}

View File

@@ -1,5 +1,6 @@
using System;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
@@ -81,7 +82,7 @@ namespace Input
else
{
Debug.Log("[InputManager] SwitchInputOnSceneLoaded - Setting InputMode to PlayerTouch");
SetInputMode(InputMode.Game);
SetInputMode(InputMode.GameAndUI);
}
}
@@ -148,6 +149,11 @@ namespace Input
/// </summary>
private void OnTapMovePerformed(InputAction.CallbackContext ctx)
{
if (EventSystem.current.IsPointerOverGameObject())
{
return;
}
Vector2 screenPos = positionAction.ReadValue<Vector2>();
Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos);
Vector2 worldPos2D = new Vector2(worldPos.x, worldPos.y);

View File

@@ -0,0 +1,142 @@
using System;
using UnityEngine;
using UnityEngine.SceneManagement;
using Input;
namespace UI
{
public class PauseMenu : MonoBehaviour
{
[Header("UI References")]
[SerializeField] private GameObject pauseMenuPanel;
[SerializeField] private GameObject pauseButton;
private void Start()
{
// Subscribe to scene loaded events
SceneManagerService.Instance.SceneLoadCompleted += SetPauseMenuByLevel;
// Set initial state based on current scene
SetPauseMenuByLevel(SceneManager.GetActiveScene().name);
// Initialize pause menu state
HidePauseMenu();
}
private void OnDestroy()
{
// Unsubscribe when destroyed
if (SceneManagerService.Instance != null)
{
SceneManagerService.Instance.SceneLoadCompleted -= SetPauseMenuByLevel;
}
}
/// <summary>
/// Sets the pause menu game object active or inactive based on the current level
/// </summary>
/// <param name="levelName">The name of the level/scene</param>
public void SetPauseMenuByLevel(string levelName)
{
if (string.IsNullOrEmpty(levelName))
return;
bool isMainMenu = levelName.ToLower().Contains("mainmenu");
gameObject.SetActive(!isMainMenu);
if(!isMainMenu)
HidePauseMenu(); // Ensure menu is hidden when switching to a game level
Debug.Log($"[PauseMenu] Setting pause menu active: {!isMainMenu} for scene: {levelName}");
}
/// <summary>
/// Shows the pause menu and hides the pause button. Sets input mode to UI.
/// </summary>
public void ShowPauseMenu()
{
if (pauseMenuPanel != null)
pauseMenuPanel.SetActive(true);
if (pauseButton != null)
pauseButton.SetActive(false);
// Change input mode to UI when menu is open
InputManager.Instance.SetInputMode(InputMode.UI);
}
/// <summary>
/// Hides the pause menu and shows the pause button. Sets input mode to Game.
/// </summary>
public void HidePauseMenu()
{
if (pauseMenuPanel != null)
pauseMenuPanel.SetActive(false);
if (pauseButton != null)
pauseButton.SetActive(true);
// Change input mode back to Game when menu is closed
InputManager.Instance.SetInputMode(InputMode.Game);
}
/// <summary>
/// Resumes the game by hiding the pause menu.
/// </summary>
public void ResumeGame()
{
HidePauseMenu();
}
/// <summary>
/// Exits to the main menu scene.
/// </summary>
public async void ExitToMainMenu()
{
// Replace with the actual scene name as set in Build Settings
var progress = new Progress<float>(p => Debug.Log($"Loading progress: {p * 100:F0}%"));
await SceneManagerService.Instance.SwitchSceneAsync("MainMenu", progress);
}
/// <summary>
/// Exits the application.
/// </summary>
public void ExitGame()
{
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;
#else
Application.Quit();
#endif
}
/// <summary>
/// Loads a level based on the selection from a dropdown menu.
/// Connect this to a Dropdown's onValueChanged event and pass the selected option text.
/// </summary>
/// <param name="levelSelection">The selected level name or identifier from the dropdown</param>
public async void LoadLevel(int levelSelection)
{
// Hide the pause menu before loading a new level
HidePauseMenu();
// Replace with the actual scene name as set in Build Settings
var progress = new Progress<float>(p => Debug.Log($"Loading progress: {p * 100:F0}%"));
switch (levelSelection)
{
case 0:
await SceneManagerService.Instance.SwitchSceneAsync("MainMenu", progress);
break;
case 1:
await SceneManagerService.Instance.SwitchSceneAsync("AppleHillsOverworld", progress);
break;
case 2:
await SceneManagerService.Instance.SwitchSceneAsync("Quarry", progress);
break;
case 3:
await SceneManagerService.Instance.SwitchSceneAsync("DivingForPictures", progress);
break;
}
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: cb36c2845dc855a4c980ef9dec6ca127