377 lines
9.5 KiB
C#
377 lines
9.5 KiB
C#
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;
|
||
|
||
|
||
/// <summary>
|
||
/// 旧版输入管理器,已被更灵活的基于InputInterpreter的输入系统替代
|
||
/// </summary>
|
||
[Obsolete("InputManager已被废弃,请使用新的InputInterpreter架构替代。参见Framework.InputInterpreter")]
|
||
[ObfuzIgnore]
|
||
public class InputManager : SingletonMono<InputManager>
|
||
{
|
||
/// <summary>
|
||
/// 是否激活
|
||
/// </summary>
|
||
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;
|
||
/// <summary>
|
||
/// 任意屏幕点击
|
||
/// </summary>
|
||
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<EventSystem>();
|
||
if (null == eventSystem)
|
||
{
|
||
DebugUtil.Log($"没有EventSystem,创建!");
|
||
GameObject go = new()
|
||
{
|
||
name = "EventSystem"
|
||
};
|
||
go.AddComponent<InputSystemUIInputModule>();
|
||
eventSystem = go.AddComponent<EventSystem>();
|
||
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();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 检测返回键是否按下
|
||
/// Android: Escape键触发返回
|
||
/// Editor: Escape键模拟Android返回(用于测试)
|
||
/// </summary>
|
||
/// <returns>是否按下了返回键</returns>
|
||
public bool CheckIsBackKeyDown()
|
||
{
|
||
#if UNITY_ANDROID || UNITY_EDITOR || UNITY_OPENHARMONY
|
||
|
||
if (Input.GetKeyDown(KeyCode.Escape))
|
||
{
|
||
EventManager.Instance.Send(EventManager.EventName.Android_Click_Back);
|
||
return true;
|
||
}
|
||
|
||
#endif
|
||
return false;
|
||
}
|
||
} |