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