From bc22fd013e6cab245d45dea3dfe6cb56a88ac333 Mon Sep 17 00:00:00 2001 From: AlexanderT Date: Wed, 24 Sep 2025 16:36:31 +0200 Subject: [PATCH 1/3] Add input maps for player input mode and UI" --- Assets/Input/PlayerTouchActions.inputactions | 518 ++++++++++++++++++- Assets/Prefabs/Managers/InputManager.prefab | 2 +- 2 files changed, 518 insertions(+), 2 deletions(-) diff --git a/Assets/Input/PlayerTouchActions.inputactions b/Assets/Input/PlayerTouchActions.inputactions index 5bf3e356..26c26e3b 100644 --- a/Assets/Input/PlayerTouchActions.inputactions +++ b/Assets/Input/PlayerTouchActions.inputactions @@ -3,7 +3,7 @@ "name": "PlayerTouchActions", "maps": [ { - "name": "DefaultActionMap", + "name": "PlayerTouch", "id": "53d55b3c-f7c2-4706-a857-c615ecb16ff7", "actions": [ { @@ -69,6 +69,522 @@ "isPartOfComposite": false } ] + }, + { + "name": "UI", + "id": "12cf45dc-5cb9-4cc1-b345-1169f531df44", + "actions": [ + { + "name": "Navigate", + "type": "PassThrough", + "id": "cef0a4a7-0193-44a6-bad9-f46ca2845c43", + "expectedControlType": "Vector2", + "processors": "", + "interactions": "", + "initialStateCheck": false + }, + { + "name": "Submit", + "type": "Button", + "id": "843a4564-118d-44ea-8bd3-edcdc48f98c3", + "expectedControlType": "Button", + "processors": "", + "interactions": "", + "initialStateCheck": false + }, + { + "name": "Cancel", + "type": "Button", + "id": "4a050dc0-bc3d-4941-aec6-d8d539f3e4b3", + "expectedControlType": "Button", + "processors": "", + "interactions": "", + "initialStateCheck": false + }, + { + "name": "Point", + "type": "PassThrough", + "id": "a03cf960-cfac-495c-9344-de5f5ef44bba", + "expectedControlType": "Vector2", + "processors": "", + "interactions": "", + "initialStateCheck": true + }, + { + "name": "Click", + "type": "PassThrough", + "id": "7e486236-0e6f-4f21-ade8-0ab696112f8e", + "expectedControlType": "Button", + "processors": "", + "interactions": "", + "initialStateCheck": true + }, + { + "name": "RightClick", + "type": "PassThrough", + "id": "09458b52-8a45-4617-a412-000ed647d359", + "expectedControlType": "Button", + "processors": "", + "interactions": "", + "initialStateCheck": false + }, + { + "name": "MiddleClick", + "type": "PassThrough", + "id": "7c721d8a-977d-4ff7-87b2-19dbd4eb5ea6", + "expectedControlType": "Button", + "processors": "", + "interactions": "", + "initialStateCheck": false + }, + { + "name": "ScrollWheel", + "type": "PassThrough", + "id": "e6a073b0-0030-42c2-88ef-85d828760630", + "expectedControlType": "Vector2", + "processors": "", + "interactions": "", + "initialStateCheck": false + }, + { + "name": "TrackedDevicePosition", + "type": "PassThrough", + "id": "efcff6db-3f65-4107-8658-7e56305f2c8a", + "expectedControlType": "Vector3", + "processors": "", + "interactions": "", + "initialStateCheck": false + }, + { + "name": "TrackedDeviceOrientation", + "type": "PassThrough", + "id": "2c7ed826-65c6-4dc4-81c7-536d62bbede1", + "expectedControlType": "Quaternion", + "processors": "", + "interactions": "", + "initialStateCheck": false + } + ], + "bindings": [ + { + "name": "Gamepad", + "id": "499b8c05-0325-4b99-9be0-9c8aa41ec39d", + "path": "2DVector", + "interactions": "", + "processors": "", + "groups": "", + "action": "Navigate", + "isComposite": true, + "isPartOfComposite": false + }, + { + "name": "up", + "id": "e5794321-3fc2-4ca8-a7a9-e35446b102ef", + "path": "/leftStick/up", + "interactions": "", + "processors": "", + "groups": ";Gamepad", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "up", + "id": "72f978c8-23be-4e97-8609-0b1426355553", + "path": "/rightStick/up", + "interactions": "", + "processors": "", + "groups": ";Gamepad", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "down", + "id": "6009f3e0-d95b-4440-a827-617812265049", + "path": "/leftStick/down", + "interactions": "", + "processors": "", + "groups": ";Gamepad", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "down", + "id": "590f0119-784f-45f3-97b6-5ffbfad9941f", + "path": "/rightStick/down", + "interactions": "", + "processors": "", + "groups": ";Gamepad", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "left", + "id": "e3588172-d7ee-4395-bc1a-3fc013f42400", + "path": "/leftStick/left", + "interactions": "", + "processors": "", + "groups": ";Gamepad", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "left", + "id": "4da29037-9c91-4140-8068-68a7375cdc4e", + "path": "/rightStick/left", + "interactions": "", + "processors": "", + "groups": ";Gamepad", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "right", + "id": "4620550c-3f8f-437c-a426-ad3e52b2764c", + "path": "/leftStick/right", + "interactions": "", + "processors": "", + "groups": ";Gamepad", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "right", + "id": "c74b9635-b880-45f5-a469-5cb8c2b83909", + "path": "/rightStick/right", + "interactions": "", + "processors": "", + "groups": ";Gamepad", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "", + "id": "7a2feef9-0779-498f-a6ae-08484b606d07", + "path": "/dpad", + "interactions": "", + "processors": "", + "groups": ";Gamepad", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "Joystick", + "id": "cd58a9a8-6605-4b26-8fb3-466b928fad60", + "path": "2DVector", + "interactions": "", + "processors": "", + "groups": "", + "action": "Navigate", + "isComposite": true, + "isPartOfComposite": false + }, + { + "name": "up", + "id": "be8cdff0-47f9-4546-a919-405e54580ea5", + "path": "/stick/up", + "interactions": "", + "processors": "", + "groups": "Joystick", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "down", + "id": "04487afd-6a42-471a-ae70-49d7583ad93b", + "path": "/stick/down", + "interactions": "", + "processors": "", + "groups": "Joystick", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "left", + "id": "d327788e-3a9a-4c14-97c8-b46bff05cf16", + "path": "/stick/left", + "interactions": "", + "processors": "", + "groups": "Joystick", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "right", + "id": "4c760fb6-00fc-46bc-8a0f-e1be2a3a91cd", + "path": "/stick/right", + "interactions": "", + "processors": "", + "groups": "Joystick", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "Keyboard", + "id": "21afa4c3-8c86-4939-bafc-c75c37368f04", + "path": "2DVector", + "interactions": "", + "processors": "", + "groups": "", + "action": "Navigate", + "isComposite": true, + "isPartOfComposite": false + }, + { + "name": "up", + "id": "1d6ea17c-5d6b-4ae5-9881-cf787fd492ed", + "path": "/w", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "up", + "id": "6e90418f-6f67-4248-bbb4-90243304f39a", + "path": "/upArrow", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "down", + "id": "6be3eb21-d6ea-458d-a66f-f82487ec9139", + "path": "/s", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "down", + "id": "3188c496-3978-454b-be6f-944521aabea4", + "path": "/downArrow", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "left", + "id": "00de0415-2218-4887-9ad6-e4a6c1dacc5b", + "path": "/a", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "left", + "id": "f723bc7b-263d-4619-93aa-0afdc40f3bc3", + "path": "/leftArrow", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "right", + "id": "f3530c12-f67f-437a-979e-2271af5b2d2d", + "path": "/d", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "right", + "id": "d760d39b-f0b3-4823-a705-c20b641b5720", + "path": "/rightArrow", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "", + "id": "2cc2aec1-4255-4cab-bb40-0a894a0d87d3", + "path": "*/{Submit}", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse;Gamepad;Touch;Joystick;XR", + "action": "Submit", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "fbe038e0-74cf-48bc-b013-4d6f9e817833", + "path": "*/{Cancel}", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse;Gamepad;Touch;Joystick;XR", + "action": "Cancel", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "21be382d-dc2e-4360-bdb6-a3cc412a0abe", + "path": "/position", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "Point", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "38f39dfe-e703-4be0-8fcf-6de2167518c1", + "path": "/position", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "Point", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "5bbcf2f7-aea0-4067-ae32-aaf383287fb3", + "path": "/touch*/position", + "interactions": "", + "processors": "", + "groups": "Touch", + "action": "Point", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "32dde7e0-9557-4429-a882-7c87540c7e53", + "path": "/leftButton", + "interactions": "", + "processors": "", + "groups": ";Keyboard&Mouse", + "action": "Click", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "f22741eb-66dd-4e3e-aaca-94d92991235c", + "path": "/tip", + "interactions": "", + "processors": "", + "groups": ";Keyboard&Mouse", + "action": "Click", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "1bec0af0-b75f-43da-a4a7-7de7f952df13", + "path": "/touch*/press", + "interactions": "", + "processors": "", + "groups": "Touch", + "action": "Click", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "d281b478-404c-47ec-95d3-ddcdcc19369a", + "path": "/trigger", + "interactions": "", + "processors": "", + "groups": "XR", + "action": "Click", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "ea2e7ff3-1a42-4202-8c53-abcae2467bb2", + "path": "/scroll", + "interactions": "", + "processors": "", + "groups": ";Keyboard&Mouse", + "action": "ScrollWheel", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "b0b7ca17-b763-4af6-a02a-0fcfbf043c37", + "path": "/rightButton", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "RightClick", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "c3146994-3749-4211-a80a-5766edd782e3", + "path": "/middleButton", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "MiddleClick", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "35aad27d-6a71-481b-b308-7763de690931", + "path": "/devicePosition", + "interactions": "", + "processors": "", + "groups": "XR", + "action": "TrackedDevicePosition", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "d116b82b-e40f-4ab3-b7b8-eec40f53e88a", + "path": "/deviceRotation", + "interactions": "", + "processors": "", + "groups": "XR", + "action": "TrackedDeviceOrientation", + "isComposite": false, + "isPartOfComposite": false + } + ] } ], "controlSchemes": [] diff --git a/Assets/Prefabs/Managers/InputManager.prefab b/Assets/Prefabs/Managers/InputManager.prefab index 5d900467..5c9c7d98 100644 --- a/Assets/Prefabs/Managers/InputManager.prefab +++ b/Assets/Prefabs/Managers/InputManager.prefab @@ -72,6 +72,6 @@ MonoBehaviour: m_ActionEvents: [] m_NeverAutoSwitchControlSchemes: 0 m_DefaultControlScheme: - m_DefaultActionMap: DefaultActionMap + m_DefaultActionMap: 53d55b3c-f7c2-4706-a857-c615ecb16ff7 m_SplitScreenIndex: -1 m_Camera: {fileID: 0} -- 2.49.1 From 74e65fdf429458cbca25043cb3948f18a2366f9b Mon Sep 17 00:00:00 2001 From: Michal Pikulski Date: Thu, 25 Sep 2025 10:40:17 +0200 Subject: [PATCH 2/3] InputModeSwitching in InputManager and no more player input during UI pop ups --- Assets/Scenes/Levels/Quarry.unity | 45 +++ Assets/Scripts/Input/InputManager.cs | 331 +++++++++++------- Assets/Scripts/LevelS/LevelSwitch.cs | 3 + .../Player/PlayerController.cs | 1 + Assets/Scripts/Test.meta | 8 + Assets/Settings/DivingMinigameSettings.asset | 2 +- 6 files changed, 253 insertions(+), 137 deletions(-) create mode 100644 Assets/Scripts/Test.meta diff --git a/Assets/Scenes/Levels/Quarry.unity b/Assets/Scenes/Levels/Quarry.unity index 673cb870..9e8349f1 100644 --- a/Assets/Scenes/Levels/Quarry.unity +++ b/Assets/Scenes/Levels/Quarry.unity @@ -438175,6 +438175,50 @@ 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 @@ -445420,3 +445464,4 @@ SceneRoots: - {fileID: 122256018} - {fileID: 1101333109} - {fileID: 4912039252317080710} + - {fileID: 1360662870} diff --git a/Assets/Scripts/Input/InputManager.cs b/Assets/Scripts/Input/InputManager.cs index bf8081d9..e244a232 100644 --- a/Assets/Scripts/Input/InputManager.cs +++ b/Assets/Scripts/Input/InputManager.cs @@ -1,175 +1,234 @@ -using UnityEngine; +using System; +using UnityEngine; using UnityEngine.InputSystem; +using UnityEngine.SceneManagement; -/// -/// Handles input events and dispatches them to the appropriate ITouchInputConsumer. -/// Supports tap and hold/drag logic, with interactable delegation and debug logging. -/// -public class InputManager : MonoBehaviour +namespace Input { - private static InputManager _instance; - private static bool _isQuitting = false; - - public static InputManager Instance + public enum InputMode { - get + Game, + UI, + GameAndUI, + InputDisabled + } + + /// + /// Handles input events and dispatches them to the appropriate ITouchInputConsumer. + /// Supports tap and hold/drag logic, with interactable delegation and debug logging. + /// + public class InputManager : MonoBehaviour + { + private const string UiActions = "UI"; + private const string GameActions = "PlayerTouch"; + + private static InputManager _instance; + private static bool _isQuitting = false; + + public static InputManager Instance { - if (_instance == null && Application.isPlaying && !_isQuitting) + get { - _instance = FindAnyObjectByType(); - if (_instance == null) + if (_instance == null && Application.isPlaying && !_isQuitting) { - var go = new GameObject("InputManager"); - _instance = go.AddComponent(); - // DontDestroyOnLoad(go); + _instance = FindAnyObjectByType(); + if (_instance == null) + { + var go = new GameObject("InputManager"); + _instance = go.AddComponent(); + // DontDestroyOnLoad(go); + } } + return _instance; } - return _instance; } - } - private PlayerInput playerInput; - private InputAction tapMoveAction; - private InputAction holdMoveAction; - private InputAction positionAction; - private ITouchInputConsumer defaultConsumer; - private bool isHoldActive; + private PlayerInput playerInput; + private InputAction tapMoveAction; + private InputAction holdMoveAction; + private InputAction positionAction; + private ITouchInputConsumer defaultConsumer; + private bool isHoldActive; - void Awake() - { - _instance = this; - // DontDestroyOnLoad(gameObject); - playerInput = GetComponent(); - if (playerInput == null) + void Awake() { - Debug.LogError("[InputManager] InputManager requires a PlayerInput component attached to the same GameObject."); - return; + _instance = this; + // DontDestroyOnLoad(gameObject); + playerInput = GetComponent(); + if (playerInput == null) + { + Debug.LogError("[InputManager] InputManager requires a PlayerInput component attached to the same GameObject."); + return; + } + tapMoveAction = playerInput.actions.FindAction("TapMove", false); + holdMoveAction = playerInput.actions.FindAction("HoldMove", false); + positionAction = playerInput.actions.FindAction("TouchPosition", false); } - tapMoveAction = playerInput.actions.FindAction("TapMove", false); - holdMoveAction = playerInput.actions.FindAction("HoldMove", false); - positionAction = playerInput.actions.FindAction("TouchPosition", false); - } - void OnEnable() - { - if (tapMoveAction != null) - tapMoveAction.performed += OnTapMovePerformed; - if (holdMoveAction != null) + private void Start() { - holdMoveAction.performed += OnHoldMoveStarted; - holdMoveAction.canceled += OnHoldMoveCanceled; + SceneManagerService.Instance.SceneLoadCompleted += SwitchInputOnSceneLoaded; + SwitchInputOnSceneLoaded(SceneManager.GetActiveScene().name); } - } - void OnDisable() - { - if (tapMoveAction != null) - tapMoveAction.performed -= OnTapMovePerformed; - if (holdMoveAction != null) + private void SwitchInputOnSceneLoaded(string sceneName) { - holdMoveAction.performed -= OnHoldMoveStarted; - holdMoveAction.canceled -= OnHoldMoveCanceled; + if (sceneName.ToLower().Contains("mainmenu")) + { + Debug.Log("[InputManager] SwitchInputOnSceneLoaded - Setting InputMode to UI for MainMenu"); + SetInputMode(InputMode.UI); + } + else + { + Debug.Log("[InputManager] SwitchInputOnSceneLoaded - Setting InputMode to PlayerTouch"); + SetInputMode(InputMode.Game); + } } - } - void OnApplicationQuit() - { - _isQuitting = true; - } - - /// - /// Sets the default ITouchInputConsumer to receive input events. - /// - public void SetDefaultConsumer(ITouchInputConsumer consumer) - { - defaultConsumer = consumer; - } - - /// - /// Handles tap input, delegates to interactable if present, otherwise to default consumer. - /// - private void OnTapMovePerformed(InputAction.CallbackContext ctx) - { - Vector2 screenPos = positionAction.ReadValue(); - Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos); - Vector2 worldPos2D = new Vector2(worldPos.x, worldPos.y); - Debug.Log($"[InputManager] TapMove performed at {worldPos2D}"); - if (!TryDelegateToInteractable(worldPos2D)) + public void SetInputMode(InputMode inputMode) { - Debug.Log("[InputManager] No interactable found, forwarding tap to default consumer"); - defaultConsumer?.OnTap(worldPos2D); + switch (inputMode) + { + case InputMode.UI: + playerInput.actions.FindActionMap(UiActions).Enable(); + playerInput.actions.FindActionMap(GameActions).Disable(); + break; + case InputMode.Game: + playerInput.actions.FindActionMap(UiActions).Disable(); + playerInput.actions.FindActionMap(GameActions).Enable(); + break; + case InputMode.GameAndUI: + playerInput.actions.FindActionMap(UiActions).Enable(); + playerInput.actions.FindActionMap(GameActions).Enable(); + break; + case InputMode.InputDisabled: + playerInput.actions.FindActionMap(UiActions).Disable(); + playerInput.actions.FindActionMap(GameActions).Disable(); + break; + } } - else + + void OnEnable() { - Debug.Log("[InputManager] Tap delegated to interactable"); + if (tapMoveAction != null) + tapMoveAction.performed += OnTapMovePerformed; + if (holdMoveAction != null) + { + holdMoveAction.performed += OnHoldMoveStarted; + holdMoveAction.canceled += OnHoldMoveCanceled; + } } - } - /// - /// Handles the start of a hold input. - /// - private void OnHoldMoveStarted(InputAction.CallbackContext ctx) - { - isHoldActive = true; - Vector2 screenPos = positionAction.ReadValue(); - Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos); - Vector2 worldPos2D = new Vector2(worldPos.x, worldPos.y); - Debug.Log($"[InputManager] HoldMove started at {worldPos2D}"); - defaultConsumer?.OnHoldStart(worldPos2D); - } + void OnDisable() + { + if (tapMoveAction != null) + tapMoveAction.performed -= OnTapMovePerformed; + if (holdMoveAction != null) + { + holdMoveAction.performed -= OnHoldMoveStarted; + holdMoveAction.canceled -= OnHoldMoveCanceled; + } + } - /// - /// Handles the end of a hold input. - /// - private void OnHoldMoveCanceled(InputAction.CallbackContext ctx) - { - if (!isHoldActive) return; - isHoldActive = false; - Vector2 screenPos = positionAction.ReadValue(); - Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos); - Vector2 worldPos2D = new Vector2(worldPos.x, worldPos.y); - Debug.Log($"[InputManager] HoldMove canceled at {worldPos2D}"); - defaultConsumer?.OnHoldEnd(worldPos2D); - } + void OnApplicationQuit() + { + _isQuitting = true; + } - /// - /// Continuously updates hold move input while active. - /// - void Update() - { - if (isHoldActive && holdMoveAction != null && holdMoveAction.phase == InputActionPhase.Performed) + /// + /// Sets the default ITouchInputConsumer to receive input events. + /// + public void SetDefaultConsumer(ITouchInputConsumer consumer) + { + defaultConsumer = consumer; + } + + /// + /// Handles tap input, delegates to interactable if present, otherwise to default consumer. + /// + private void OnTapMovePerformed(InputAction.CallbackContext ctx) { Vector2 screenPos = positionAction.ReadValue(); Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos); Vector2 worldPos2D = new Vector2(worldPos.x, worldPos.y); - // Debug.Log($"[InputManager] HoldMove update at {worldPos2D}"); - defaultConsumer?.OnHoldMove(worldPos2D); - } - } - - /// - /// Attempts to delegate a tap to an interactable at the given world position. - /// Traces on the "Interactable" channel and logs detailed info. - /// - private bool TryDelegateToInteractable(Vector2 worldPos) - { - LayerMask mask = GameManager.Instance != null ? GameManager.Instance.InteractableLayerMask : -1; - Collider2D hit = Physics2D.OverlapPoint(worldPos, mask); - if (hit != null) - { - var consumer = hit.GetComponent(); - if (consumer != null) + Debug.Log($"[InputManager] TapMove performed at {worldPos2D}"); + if (!TryDelegateToInteractable(worldPos2D)) { - Debug.unityLogger.Log("Interactable", $"[InputManager] Delegating tap to consumer at {worldPos} (GameObject: {hit.gameObject.name})"); - consumer.OnTap(worldPos); - return true; + Debug.Log("[InputManager] No interactable found, forwarding tap to default consumer"); + defaultConsumer?.OnTap(worldPos2D); + } + else + { + Debug.Log("[InputManager] Tap delegated to interactable"); } - Debug.unityLogger.Log("Interactable", $"[InputManager] Collider2D hit at {worldPos} (GameObject: {hit.gameObject.name}), but no ITouchInputConsumer found."); } - else + + /// + /// Handles the start of a hold input. + /// + private void OnHoldMoveStarted(InputAction.CallbackContext ctx) { - Debug.unityLogger.Log("Interactable", $"[InputManager] No Collider2D found at {worldPos} for interactable delegation."); + isHoldActive = true; + Vector2 screenPos = positionAction.ReadValue(); + Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos); + Vector2 worldPos2D = new Vector2(worldPos.x, worldPos.y); + Debug.Log($"[InputManager] HoldMove started at {worldPos2D}"); + defaultConsumer?.OnHoldStart(worldPos2D); + } + + /// + /// Handles the end of a hold input. + /// + private void OnHoldMoveCanceled(InputAction.CallbackContext ctx) + { + if (!isHoldActive) return; + isHoldActive = false; + Vector2 screenPos = positionAction.ReadValue(); + Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos); + Vector2 worldPos2D = new Vector2(worldPos.x, worldPos.y); + Debug.Log($"[InputManager] HoldMove canceled at {worldPos2D}"); + defaultConsumer?.OnHoldEnd(worldPos2D); + } + + /// + /// Continuously updates hold move input while active. + /// + void Update() + { + if (isHoldActive && holdMoveAction != null && holdMoveAction.phase == InputActionPhase.Performed) + { + Vector2 screenPos = positionAction.ReadValue(); + Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos); + Vector2 worldPos2D = new Vector2(worldPos.x, worldPos.y); + // Debug.Log($"[InputManager] HoldMove update at {worldPos2D}"); + defaultConsumer?.OnHoldMove(worldPos2D); + } + } + + /// + /// Attempts to delegate a tap to an interactable at the given world position. + /// Traces on the "Interactable" channel and logs detailed info. + /// + private bool TryDelegateToInteractable(Vector2 worldPos) + { + LayerMask mask = GameManager.Instance != null ? GameManager.Instance.InteractableLayerMask : -1; + Collider2D hit = Physics2D.OverlapPoint(worldPos, mask); + if (hit != null) + { + var consumer = hit.GetComponent(); + if (consumer != null) + { + Debug.unityLogger.Log("Interactable", $"[InputManager] Delegating tap to consumer at {worldPos} (GameObject: {hit.gameObject.name})"); + consumer.OnTap(worldPos); + return true; + } + Debug.unityLogger.Log("Interactable", $"[InputManager] Collider2D hit at {worldPos} (GameObject: {hit.gameObject.name}), but no ITouchInputConsumer found."); + } + else + { + Debug.unityLogger.Log("Interactable", $"[InputManager] No Collider2D found at {worldPos} for interactable delegation."); + } + return false; } - return false; } } diff --git a/Assets/Scripts/LevelS/LevelSwitch.cs b/Assets/Scripts/LevelS/LevelSwitch.cs index cbc29ff6..36d39fc5 100644 --- a/Assets/Scripts/LevelS/LevelSwitch.cs +++ b/Assets/Scripts/LevelS/LevelSwitch.cs @@ -96,6 +96,9 @@ public class LevelSwitch : MonoBehaviour // Setup menu with data and callbacks menu.Setup(switchData, OnMenuConfirm, OnMenuCancel); _isActive = false; // Prevent re-triggering until menu is closed + + // Switch input mode to UI only + InputManager.Instance.SetInputMode(InputMode.UI); } private async void OnMenuConfirm() diff --git a/Assets/Scripts/Minigames/DivingForPictures/Player/PlayerController.cs b/Assets/Scripts/Minigames/DivingForPictures/Player/PlayerController.cs index 9c3fa3cf..5a974a54 100644 --- a/Assets/Scripts/Minigames/DivingForPictures/Player/PlayerController.cs +++ b/Assets/Scripts/Minigames/DivingForPictures/Player/PlayerController.cs @@ -1,5 +1,6 @@ using UnityEngine; using AppleHills.Core.Settings; +using Input; namespace Minigames.DivingForPictures { diff --git a/Assets/Scripts/Test.meta b/Assets/Scripts/Test.meta new file mode 100644 index 00000000..f10bb29a --- /dev/null +++ b/Assets/Scripts/Test.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 23fdb60880dd05846a6e0d3681a02242 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Settings/DivingMinigameSettings.asset b/Assets/Settings/DivingMinigameSettings.asset index 766926f6..58d56dd8 100644 --- a/Assets/Settings/DivingMinigameSettings.asset +++ b/Assets/Settings/DivingMinigameSettings.asset @@ -31,7 +31,7 @@ MonoBehaviour: surfacingSpawnDelay: 5 initialTileCount: 3 tileSpawnBuffer: 1 - moveSpeed: 2 + moveSpeed: 1 speedUpFactor: 0 speedUpInterval: 10 maxMoveSpeed: 12 -- 2.49.1 From 05753cc214d0c718af22a66c91b62292e3d71920 Mon Sep 17 00:00:00 2001 From: Michal Pikulski Date: Thu, 25 Sep 2025 12:02:18 +0200 Subject: [PATCH 3/3] Add a pause menu, auto load via bootstrap and correctly show depending on the current scene --- Assets/Art/Textures/MenuIcon_PLACEHOLDER.png | Bin 0 -> 6169 bytes .../Textures/MenuIcon_PLACEHOLDER.png.meta | 195 ++ .../Runtime/CustomBootSettings_Runtime.asset | 1 + .../LiberationSans SDF.asset | 399 ++- Assets/Prefabs/UI/PauseMenu.prefab | 2500 +++++++++++++++++ Assets/Prefabs/UI/PauseMenu.prefab.meta | 7 + .../Scenes/Levels/AppleHillsOverworld.unity | 32 + Assets/Scenes/Levels/Quarry.unity | 45 - Assets/Scripts/Input/InputManager.cs | 8 +- Assets/Scripts/UI/PauseMenu.cs | 142 + Assets/Scripts/UI/PauseMenu.cs.meta | 2 + 11 files changed, 3223 insertions(+), 108 deletions(-) create mode 100644 Assets/Art/Textures/MenuIcon_PLACEHOLDER.png create mode 100644 Assets/Art/Textures/MenuIcon_PLACEHOLDER.png.meta create mode 100644 Assets/Prefabs/UI/PauseMenu.prefab create mode 100644 Assets/Prefabs/UI/PauseMenu.prefab.meta create mode 100644 Assets/Scripts/UI/PauseMenu.cs create mode 100644 Assets/Scripts/UI/PauseMenu.cs.meta diff --git a/Assets/Art/Textures/MenuIcon_PLACEHOLDER.png b/Assets/Art/Textures/MenuIcon_PLACEHOLDER.png new file mode 100644 index 0000000000000000000000000000000000000000..21111f579defc3ab694173d631fab1a0fa53f108 GIT binary patch literal 6169 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 private void OnTapMovePerformed(InputAction.CallbackContext ctx) { + if (EventSystem.current.IsPointerOverGameObject()) + { + return; + } + Vector2 screenPos = positionAction.ReadValue(); Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos); Vector2 worldPos2D = new Vector2(worldPos.x, worldPos.y); diff --git a/Assets/Scripts/UI/PauseMenu.cs b/Assets/Scripts/UI/PauseMenu.cs new file mode 100644 index 00000000..7b1f0efc --- /dev/null +++ b/Assets/Scripts/UI/PauseMenu.cs @@ -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; + } + } + + /// + /// Sets the pause menu game object active or inactive based on the current level + /// + /// The name of the level/scene + 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}"); + } + + /// + /// Shows the pause menu and hides the pause button. Sets input mode to UI. + /// + 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); + } + + /// + /// Hides the pause menu and shows the pause button. Sets input mode to Game. + /// + 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); + } + + /// + /// Resumes the game by hiding the pause menu. + /// + public void ResumeGame() + { + HidePauseMenu(); + } + + /// + /// Exits to the main menu scene. + /// + public async void ExitToMainMenu() + { + // Replace with the actual scene name as set in Build Settings + var progress = new Progress(p => Debug.Log($"Loading progress: {p * 100:F0}%")); + await SceneManagerService.Instance.SwitchSceneAsync("MainMenu", progress); + } + + /// + /// Exits the application. + /// + public void ExitGame() + { +#if UNITY_EDITOR + UnityEditor.EditorApplication.isPlaying = false; +#else + Application.Quit(); +#endif + } + + /// + /// 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. + /// + /// The selected level name or identifier from the dropdown + 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(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; + } + } + } +} diff --git a/Assets/Scripts/UI/PauseMenu.cs.meta b/Assets/Scripts/UI/PauseMenu.cs.meta new file mode 100644 index 00000000..bfa85656 --- /dev/null +++ b/Assets/Scripts/UI/PauseMenu.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: cb36c2845dc855a4c980ef9dec6ca127 \ No newline at end of file -- 2.49.1