using System;
using Framework;
using Obfuz;
using PhxhSDK;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.EnhancedTouch;
using UnityEngine.InputSystem.UI;
using Touch = UnityEngine.InputSystem.EnhancedTouch.Touch;
///
/// 旧版输入管理器,已被更灵活的基于InputInterpreter的输入系统替代
///
[Obsolete("InputManager已被废弃,请使用新的InputInterpreter架构替代。参见Framework.InputInterpreter")]
[ObfuzIgnore]
public class InputManager : SingletonMono
{
///
/// 是否激活
///
public bool IsEnable;
public delegate void OnFingerMoveEvent(Vector2 delta);
public delegate void OnFingerUpEvent(Vector2 screenPosition);
public delegate void OnFingersMoveEvent(float delta);
public delegate void OnAnyClickEvent();
public OnFingerMoveEvent OnFingerMove;
public OnFingerMoveEvent OnFingerMoveUI;
public OnFingerUpEvent OnFingerUp;
public OnFingerUpEvent OnFingerUpUI;
public OnFingerUpEvent OnClick;
///
/// 任意屏幕点击
///
public OnAnyClickEvent OnAnyClick;
public OnFingersMoveEvent OnFingersMove;
private bool handledThisFrame;
private bool isOverUI = false;
public bool IsOverUI => isOverUI;
# if UNITY_STANDALONE || UNITY_EDITOR
private float moveDelta = 2f;
private bool isMousePressedLastFrame;
private bool isGuidePressLastFrame;
private bool isMouseMovedSincePressed;
private Vector2 lastMousePosition;
private ButtonControl mouseButtonAsFinger;
private bool isMosuePressUI;
#endif
private void Awake()
{
IsEnable = true;
DontDestroyOnLoad(gameObject);
EventSystem eventSystem = FindObjectOfType();
if (null == eventSystem)
{
DebugUtil.Log($"没有EventSystem,创建!");
GameObject go = new()
{
name = "EventSystem"
};
go.AddComponent();
eventSystem = go.AddComponent();
DontDestroyOnLoad(go);
return;
}
DontDestroyOnLoad(eventSystem.gameObject);
}
private void OnEnable()
{
EnhancedTouchSupport.Enable();
Touch.onFingerMove += _OnFingerMove;
Touch.onFingerUp += _OnFingerUp;
# if UNITY_STANDALONE || UNITY_EDITOR
mouseButtonAsFinger = Mouse.current.leftButton;
#endif
}
private void OnDisable()
{
Touch.onFingerMove -= _OnFingerMove;
Touch.onFingerUp -= _OnFingerUp;
EnhancedTouchSupport.Disable();
}
private void Update()
{
if (!IsEnable)
return;
isOverUI = IsPointerOverUI();
//CheckIsBackKeyDown();
#if UNITY_STANDALONE || UNITY_EDITOR
if (isGuidePressLastFrame && !mouseButtonAsFinger.isPressed)
OnAnyClick?.Invoke();
isGuidePressLastFrame = mouseButtonAsFinger.isPressed;
if (IsPointerOverUI() && mouseButtonAsFinger.isPressed && !isMousePressedLastFrame)
isMosuePressUI = true;
if (!IsPointerOverUI() && !mouseButtonAsFinger.isPressed)
isMosuePressUI = false;
var currentMouse = Mouse.current;
if (isMousePressedLastFrame && mouseButtonAsFinger.isPressed)
{
var delta = currentMouse.position.ReadValue() - lastMousePosition;
isMouseMovedSincePressed |= delta.sqrMagnitude > float.Epsilon;
if (IsPointerOverUI() || isMosuePressUI)
OnFingerMoveUI?.Invoke(delta);
else
OnFingerMove?.Invoke(delta);
}
if (!IsPointerOverUI() && !isMosuePressUI)
{
if (isMousePressedLastFrame && !mouseButtonAsFinger.isPressed)
{
if (!isMouseMovedSincePressed)
{
OnClick?.Invoke(currentMouse.position.ReadValue());
}
OnFingerUp?.Invoke(currentMouse.position.ReadValue());
isMouseMovedSincePressed = false;
}
}
if (IsPointerOverUI())
{
if (isMousePressedLastFrame && !mouseButtonAsFinger.isPressed)
{
OnFingerUpUI?.Invoke(currentMouse.position.ReadValue());
isMouseMovedSincePressed = false;
}
}
// cache mouse state for next frame
isMousePressedLastFrame = mouseButtonAsFinger.isPressed;
if (isMousePressedLastFrame)
lastMousePosition = currentMouse.position.ReadValue();
if (Mouse.current.scroll.ReadValue().y != 0)
{
OnFingersMove?.Invoke(Mouse.current.scroll.ReadValue().y);
}
if (Keyboard.current.aKey.isPressed)
{
OnFingerMove?.Invoke(new Vector2(moveDelta, 0));
}
if (Keyboard.current.dKey.isPressed)
{
OnFingerMove?.Invoke(new Vector2(-moveDelta, 0));
}
if (Keyboard.current.wKey.isPressed)
{
OnFingerMove?.Invoke(new Vector2(0, -moveDelta));
}
if (Keyboard.current.sKey.isPressed)
{
OnFingerMove?.Invoke(new Vector2(0, moveDelta));
}
#endif
}
private void LateUpdate()
{
handledThisFrame = false;
}
# if UNITY_STANDALONE || UNITY_EDITOR
public bool IsLeftButton(int buttonIndex)
{
return buttonIndex == 1;
}
public bool IsRightButton(int buttonIndex)
{
return buttonIndex == 2;
}
#endif
public void SetHandledThisFrame()
{
handledThisFrame = true;
}
public bool HandledThisFrame()
{
return handledThisFrame;
}
public bool HasTouch()
{
#if UNITY_EDITOR || UNITY_STANDALONE
return mouseButtonAsFinger?.isPressed ?? false;
#else
return Touch.activeTouches.Count > 0;
#endif
}
public Vector2 GetTouchPosition()
{
#if UNITY_EDITOR || UNITY_STANDALONE
return Mouse.current?.position.ReadValue() ?? Vector2.zero;
#else
if (Touch.activeTouches.Count > 0)
{
return Touch.activeTouches[0].screenPosition;
}
if (Mouse.current != null)
{
return Mouse.current.position.ReadValue();
}
return Vector2.zero;
#endif
}
private void _OnFingerUp(Finger finger)
{
var touch = Touch.activeTouches[0];
if (UnityEngine.InputSystem.TouchPhase.Ended == touch.phase)
OnAnyClick?.Invoke();
if (isOverUI)
{
OnFingerUpUI?.Invoke(touch.screenPosition);
return;
}
if (finger.currentTouch.delta.sqrMagnitude < float.Epsilon)
OnClick?.Invoke(touch.screenPosition);
OnFingerUp?.Invoke(touch.screenPosition);
}
private Vector2 touch1PrevPos;
private Vector2 touch2PrevPos;
private float prevTouchDeltaMag;
private void _OnFingerMove(Finger finger)
{
if (Touch.activeTouches.Count == 1)
{
var touch = Touch.activeTouches[0];
if (touch.phase == UnityEngine.InputSystem.TouchPhase.Moved)
{
if (isOverUI)
{
OnFingerMoveUI?.Invoke(touch.delta);
}
else
{
OnFingerMove?.Invoke(touch.delta);
}
}
}
else if (Touch.activeTouches.Count >= 2)
{
var touch1 = Touch.activeTouches[0];
var touch2 = Touch.activeTouches[1];
if (touch1.phase == UnityEngine.InputSystem.TouchPhase.Moved &&
touch2.phase == UnityEngine.InputSystem.TouchPhase.Moved)
{
var touch1Pos = touch1.screenPosition;
var touch2Pos = touch2.screenPosition;
var deltaPos1 = touch1Pos - touch1PrevPos;
var deltaPos2 = touch2Pos - touch2PrevPos;
var touchDeltaMag = (touch1Pos - touch2Pos).magnitude;
var deltaMagnitudeDiff = touchDeltaMag - prevTouchDeltaMag;
OnFingersMove?.Invoke(deltaMagnitudeDiff);
touch1PrevPos = touch1Pos;
touch2PrevPos = touch2Pos;
prevTouchDeltaMag = touchDeltaMag;
}
else if (touch1.phase == UnityEngine.InputSystem.TouchPhase.Began &&
touch2.phase == UnityEngine.InputSystem.TouchPhase.Began)
{
touch1PrevPos = touch1.screenPosition;
touch2PrevPos = touch2.screenPosition;
prevTouchDeltaMag = (touch1PrevPos - touch2PrevPos).magnitude;
}
}
}
private bool IsPointerOverUI(int pointerId)
{
return EventSystem.current.IsPointerOverGameObject(pointerId);
}
private bool IsPointerOverUI()
{
return EventSystem.current.IsPointerOverGameObject();
}
///
/// 检测返回键是否按下
/// Android: Escape键触发返回
/// Editor: Escape键模拟Android返回(用于测试)
///
/// 是否按下了返回键
public bool CheckIsBackKeyDown()
{
#if UNITY_ANDROID || UNITY_EDITOR
if (Input.GetKeyDown(KeyCode.Escape))
{
EventManager.Instance.Send(EventManager.EventName.Android_Click_Back);
return true;
}
#endif
return false;
}
}