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; 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 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 (IsPointerOverUI() && mouseButtonAsFinger.isPressed && !isMousePressedLastFrame) { isMosuePressUI = true; } if (!IsPointerOverUI() && !mouseButtonAsFinger.isPressed) { isMosuePressUI = false; } var currentMouse = Mouse.current; if (!isMousePressedLastFrame && mouseButtonAsFinger.isPressed) OnAnyClick?.Invoke(); 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]; 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(); } public bool CheckIsBackKeyDown() { #if UNITY_ANDROID if (Input.GetKeyDown(KeyCode.Escape)) { EventManager.Instance.Send(EventManager.EventName.Android_Click_Back); return true; } #endif return false; } }