Files
AppleHillsProduction/Assets/Scripts/InputManager.cs

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;
}
}