143 lines
4.5 KiB
C#
143 lines
4.5 KiB
C#
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
using System;
|
|
|
|
public class InputManager : MonoBehaviour
|
|
{
|
|
private static InputManager _instance;
|
|
public static InputManager Instance
|
|
{
|
|
get
|
|
{
|
|
if (_instance == null)
|
|
{
|
|
_instance = FindAnyObjectByType<InputManager>();
|
|
if (_instance == null)
|
|
{
|
|
var go = new GameObject("InputManager");
|
|
_instance = go.AddComponent<InputManager>();
|
|
DontDestroyOnLoad(go);
|
|
}
|
|
}
|
|
return _instance;
|
|
}
|
|
}
|
|
|
|
private PlayerInput playerInput;
|
|
private InputAction touchPressAction;
|
|
private InputAction touchPositionAction;
|
|
private ITouchInputConsumer defaultConsumer;
|
|
|
|
private bool isTouchHeld = false;
|
|
private bool lastFrameInteracted = false;
|
|
|
|
void Awake()
|
|
{
|
|
if (_instance != null && _instance != this)
|
|
{
|
|
Destroy(gameObject);
|
|
return;
|
|
}
|
|
_instance = this;
|
|
DontDestroyOnLoad(gameObject);
|
|
playerInput = GetComponent<PlayerInput>();
|
|
if (playerInput == null)
|
|
{
|
|
Debug.LogError("[InputManager] InputManager requires a PlayerInput component attached to the same GameObject.");
|
|
return;
|
|
}
|
|
// Find actions by name in the assigned action map
|
|
touchPressAction = playerInput.actions.FindAction("TouchPress", false);
|
|
touchPositionAction = playerInput.actions.FindAction("TouchPosition", false);
|
|
}
|
|
|
|
void OnEnable()
|
|
{
|
|
if (touchPressAction != null)
|
|
{
|
|
touchPressAction.started += OnTouchPressStarted;
|
|
touchPressAction.canceled += OnTouchPressCanceled;
|
|
}
|
|
if (touchPositionAction != null)
|
|
touchPositionAction.performed += OnTouchPositionPerformed;
|
|
}
|
|
|
|
void OnDisable()
|
|
{
|
|
if (touchPressAction != null)
|
|
{
|
|
touchPressAction.started -= OnTouchPressStarted;
|
|
touchPressAction.canceled -= OnTouchPressCanceled;
|
|
}
|
|
if (touchPositionAction != null)
|
|
touchPositionAction.performed -= OnTouchPositionPerformed;
|
|
}
|
|
|
|
public void SetDefaultConsumer(ITouchInputConsumer consumer)
|
|
{
|
|
defaultConsumer = consumer;
|
|
}
|
|
|
|
private void OnTouchPressStarted(InputAction.CallbackContext ctx)
|
|
{
|
|
// Touch started (finger down)
|
|
Vector3 _screenPos = Camera.main.ScreenToWorldPoint(touchPositionAction.ReadValue<Vector2>());
|
|
Vector2 screenPos = new Vector2(_screenPos.x, _screenPos.y);
|
|
lastFrameInteracted = TryDelegateToInteractable(screenPos);
|
|
if (!lastFrameInteracted)
|
|
defaultConsumer?.OnTouchPress(screenPos);
|
|
isTouchHeld = true;
|
|
}
|
|
|
|
private void OnTouchPressCanceled(InputAction.CallbackContext ctx)
|
|
{
|
|
// Touch released (finger up)
|
|
isTouchHeld = false;
|
|
// Reset lastFrameInteracted for next frame
|
|
lastFrameInteracted = false;
|
|
// Optionally, you can notify consumers of release if needed
|
|
}
|
|
|
|
private void OnTouchPositionPerformed(InputAction.CallbackContext ctx)
|
|
{
|
|
Vector2 pos = ctx.ReadValue<Vector2>();
|
|
if (isTouchHeld)
|
|
{
|
|
// Convert to world position
|
|
Vector3 worldPos = Camera.main.ScreenToWorldPoint(pos);
|
|
Vector2 worldPos2D = new Vector2(worldPos.x, worldPos.y);
|
|
if (!lastFrameInteracted)
|
|
defaultConsumer?.OnTouchPress(worldPos2D); // Move continuously to finger position
|
|
}
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
// Continuously advertise the last touch position while held
|
|
if (isTouchHeld && touchPositionAction != null)
|
|
{
|
|
Vector2 pos = touchPositionAction.ReadValue<Vector2>();
|
|
Vector3 worldPos = Camera.main.ScreenToWorldPoint(pos);
|
|
Vector2 worldPos2D = new Vector2(worldPos.x, worldPos.y);
|
|
if (!lastFrameInteracted)
|
|
defaultConsumer?.OnTouchPress(worldPos2D);
|
|
}
|
|
}
|
|
|
|
private bool TryDelegateToInteractable(Vector2 worldPos)
|
|
{
|
|
// Raycast at the world position to find an Interactable
|
|
Collider2D hit = Physics2D.OverlapPoint(worldPos);
|
|
if (hit != null)
|
|
{
|
|
var interactable = hit.GetComponent<Interactable>();
|
|
if (interactable != null)
|
|
{
|
|
interactable.OnTouchPress(worldPos);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
}
|