NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Framework/Input/InputManager.cs

377 lines
9.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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