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

393 lines
9.2 KiB
C#
Raw Normal View History

2024-08-27 13:29:20 +08:00
using System;
using Framework;
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>
/// 旧版输入管理器已被更灵活的基于InputUnit的输入系统替代
/// </summary>
[Obsolete("InputManager已被废弃请使用新的InputProcessor架构替代。参见Framework.InputProcessor或MigrationGuide.md了解如何迁移。")]
2024-08-27 13:29:20 +08:00
public class InputManager : SingletonMono<InputManager>
{
2024-09-09 19:34:14 +08:00
/// <summary>
/// 是否激活
/// </summary>
public bool IsEnable;
2024-08-27 13:29:20 +08:00
public delegate void OnFingerMoveEvent(Vector2 delta);
public delegate void OnFingerUpEvent(Vector2 screenPosition);
public delegate void OnFingersMoveEvent(float delta);
public delegate void OnAnyClickEvent();
2024-08-27 13:29:20 +08:00
public OnFingerMoveEvent OnFingerMove;
public OnFingerMoveEvent OnFingerMoveUI;
public OnFingerUpEvent OnFingerUp;
public OnFingerUpEvent OnFingerUpUI;
public OnFingerUpEvent OnClick;
/// <summary>
/// 任意屏幕点击
/// </summary>
public OnAnyClickEvent OnAnyClick;
2024-08-27 13:29:20 +08:00
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 isMouseMovedSincePressed;
private Vector2 lastMousePosition;
private ButtonControl mouseButtonAsFinger;
private bool isMosuePressUI;
#endif
private void Awake()
{
2024-09-09 19:34:14 +08:00
IsEnable = true;
2024-08-27 13:29:20 +08:00
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()
{
2024-09-09 19:34:14 +08:00
if (!IsEnable)
return;
2024-08-27 13:29:20 +08:00
isOverUI = IsPointerOverUI();
//CheckIsBackKeyDown();
# if UNITY_STANDALONE || UNITY_EDITOR
if (IsPointerOverUI() && mouseButtonAsFinger.isPressed && !isMousePressedLastFrame)
{
isMosuePressUI = true;
}
if (!IsPointerOverUI() && !mouseButtonAsFinger.isPressed)
{
isMosuePressUI = false;
}
var currentMouse = Mouse.current;
if (!isMousePressedLastFrame && mouseButtonAsFinger.isPressed)
OnAnyClick?.Invoke();
2024-08-27 13:29:20 +08:00
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];
2024-10-23 14:23:40 +08:00
OnAnyClick?.Invoke();
2024-08-27 13:29:20 +08:00
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();
}
public bool CheckIsBackKeyDown()
{
#if UNITY_ANDROID
if (Input.GetKeyDown(KeyCode.Escape))
{
EventManager.Instance.Send(EventManager.EventName.Android_Click_Back);
return true;
}
#endif
return false;
}
}