Add backbone for card creation and implement Camera minigame mechanics
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic; // Added for List<ITouchInputConsumer>
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.InputSystem;
|
||||
@@ -27,6 +28,9 @@ namespace Input
|
||||
private static InputManager _instance;
|
||||
private static bool _isQuitting = false;
|
||||
|
||||
// Override consumer stack - using a list to support multiple overrides that can be removed in LIFO order
|
||||
private readonly List<ITouchInputConsumer> _overrideConsumers = new List<ITouchInputConsumer>();
|
||||
|
||||
public static InputManager Instance
|
||||
{
|
||||
get
|
||||
@@ -38,7 +42,6 @@ namespace Input
|
||||
{
|
||||
var go = new GameObject("InputManager");
|
||||
_instance = go.AddComponent<InputManager>();
|
||||
// DontDestroyOnLoad(go);
|
||||
}
|
||||
}
|
||||
return _instance;
|
||||
@@ -58,7 +61,6 @@ namespace Input
|
||||
void Awake()
|
||||
{
|
||||
_instance = this;
|
||||
// DontDestroyOnLoad(gameObject);
|
||||
|
||||
// Initialize settings reference
|
||||
_interactionSettings = GameManager.GetSettingsObject<IInteractionSettings>();
|
||||
@@ -157,23 +159,27 @@ 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);
|
||||
Debug.Log($"[InputManager] TapMove performed at {worldPos2D}");
|
||||
if (!TryDelegateToInteractable(worldPos2D))
|
||||
|
||||
// First try to delegate to an override consumer if available
|
||||
if (TryDelegateToOverrideConsumer(screenPos, worldPos2D))
|
||||
{
|
||||
Debug.Log("[InputManager] No interactable found, forwarding tap to default consumer");
|
||||
Debug.Log("[InputManager] Tap delegated to override consumer");
|
||||
return;
|
||||
}
|
||||
|
||||
// Then try to delegate to any ITouchInputConsumer (UI or world interactable)
|
||||
if (!TryDelegateToAnyInputConsumer(screenPos, worldPos2D))
|
||||
{
|
||||
Debug.Log("[InputManager] No input consumer found, forwarding tap to default consumer");
|
||||
defaultConsumer?.OnTap(worldPos2D);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("[InputManager] Tap delegated to interactable");
|
||||
Debug.Log("[InputManager] Tap delegated to input consumer");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,14 +225,84 @@ namespace Input
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to delegate a tap to any ITouchInputConsumer at the given position.
|
||||
/// Checks both UI elements and world interactables.
|
||||
/// </summary>
|
||||
private bool TryDelegateToAnyInputConsumer(Vector2 screenPos, Vector2 worldPos)
|
||||
{
|
||||
// First check if we hit a UI element implementing ITouchInputConsumer
|
||||
if (TryDelegateToUIInputConsumer(screenPos))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// If no UI element with ITouchInputConsumer, try world interactables
|
||||
return TryDelegateToInteractable(worldPos);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to delegate a tap to a UI element implementing ITouchInputConsumer.
|
||||
/// </summary>
|
||||
private bool TryDelegateToUIInputConsumer(Vector2 screenPos)
|
||||
{
|
||||
// Check for UI elements under the pointer
|
||||
var eventData = new PointerEventData(EventSystem.current)
|
||||
{
|
||||
position = screenPos
|
||||
};
|
||||
|
||||
var results = new System.Collections.Generic.List<RaycastResult>();
|
||||
EventSystem.current.RaycastAll(eventData, results);
|
||||
|
||||
foreach (var result in results)
|
||||
{
|
||||
// Try to get ITouchInputConsumer component
|
||||
var consumer = result.gameObject.GetComponent<ITouchInputConsumer>();
|
||||
if (consumer == null)
|
||||
{
|
||||
consumer = result.gameObject.GetComponentInParent<ITouchInputConsumer>();
|
||||
}
|
||||
if (consumer != null)
|
||||
{
|
||||
Debug.unityLogger.Log("Interactable", $"[InputManager] Delegating tap to UI consumer at {screenPos} (GameObject: {result.gameObject.name})");
|
||||
consumer.OnTap(screenPos);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to delegate a tap to an interactable at the given world position.
|
||||
/// Traces on the "Interactable" channel and logs detailed info.
|
||||
/// </summary>
|
||||
private bool TryDelegateToInteractable(Vector2 worldPos)
|
||||
{
|
||||
LayerMask mask = _interactionSettings != null ? _interactionSettings.InteractableLayerMask : -1;
|
||||
Collider2D hit = Physics2D.OverlapPoint(worldPos, mask);
|
||||
// First try with the interaction layer mask if available
|
||||
if (_interactionSettings != null)
|
||||
{
|
||||
LayerMask mask = _interactionSettings.InteractableLayerMask;
|
||||
Collider2D hitWithMask = Physics2D.OverlapPoint(worldPos, mask);
|
||||
if (hitWithMask != null)
|
||||
{
|
||||
var consumer = hitWithMask.GetComponent<ITouchInputConsumer>();
|
||||
if (consumer == null)
|
||||
{
|
||||
consumer = hitWithMask.GetComponentInParent<ITouchInputConsumer>();
|
||||
}
|
||||
if (consumer != null)
|
||||
{
|
||||
Debug.unityLogger.Log("Interactable", $"[InputManager] Delegating tap to consumer at {worldPos} (GameObject: {hitWithMask.gameObject.name})");
|
||||
consumer.OnTap(worldPos);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no hit with the mask or no settings available, try with all colliders
|
||||
Collider2D hit = Physics2D.OverlapPoint(worldPos);
|
||||
if (hit != null)
|
||||
{
|
||||
var consumer = hit.GetComponent<ITouchInputConsumer>();
|
||||
@@ -244,5 +320,54 @@ namespace Input
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers an override consumer to receive input events.
|
||||
/// The most recently registered consumer will receive input first.
|
||||
/// </summary>
|
||||
public void RegisterOverrideConsumer(ITouchInputConsumer consumer)
|
||||
{
|
||||
if (consumer == null || _overrideConsumers.Contains(consumer))
|
||||
return;
|
||||
|
||||
_overrideConsumers.Add(consumer);
|
||||
Debug.Log($"[InputManager] Override consumer registered: {consumer}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unregisters an override consumer, removing it from the input event delegation.
|
||||
/// </summary>
|
||||
public void UnregisterOverrideConsumer(ITouchInputConsumer consumer)
|
||||
{
|
||||
if (consumer == null || !_overrideConsumers.Contains(consumer))
|
||||
return;
|
||||
|
||||
_overrideConsumers.Remove(consumer);
|
||||
Debug.Log($"[InputManager] Override consumer unregistered: {consumer}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all registered override consumers.
|
||||
/// </summary>
|
||||
public void ClearOverrideConsumers()
|
||||
{
|
||||
_overrideConsumers.Clear();
|
||||
Debug.Log("[InputManager] All override consumers cleared.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to delegate a tap to the topmost registered override consumer, if any.
|
||||
/// </summary>
|
||||
private bool TryDelegateToOverrideConsumer(Vector2 screenPos, Vector2 worldPos)
|
||||
{
|
||||
if (_overrideConsumers.Count == 0)
|
||||
return false;
|
||||
|
||||
// Get the topmost override consumer (last registered)
|
||||
var consumer = _overrideConsumers[_overrideConsumers.Count - 1];
|
||||
Debug.unityLogger.Log("Interactable", $"[InputManager] Delegating tap to override consumer at {worldPos} (GameObject: {consumer})");
|
||||
consumer.OnTap(worldPos);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user