| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- using System;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.EventSystems;
- using UnityEngine.UI;
-
- namespace JC.Unity {
-
- /**模拟鼠标-场景中需要存在EventSystem */
- public class SimulateMouse : MonoBehaviour
- {
- [SerializeField] CanvasScaler canvasScaler;
- [SerializeField] RectTransform mousePointer;
- [NonSerialized] public Action<Selectable> OnPointerEnter;
- [NonSerialized] public Action<Selectable> OnPointerClick;
- ScreenRayRaycasterUIWrapper mScreenRayRaycasterUIWrapper = new ScreenRayRaycasterUIWrapper();
-
- void Awake()
- {
- mousePointer.anchorMin = Vector2.zero;
- mousePointer.anchorMax = Vector2.zero;
-
- if (mScreenRayRaycasterUIWrapper != null) {
- // 把鼠标的位置传 Ray 发射位置
- mScreenRayRaycasterUIWrapper.Init(this, () => {
- Vector2 pos = mousePointer.anchoredPosition;
- pos.x *= (float) Screen.width / GetScaleScreenWidth();
- pos.y *= (float) Screen.height / GetScaleScreenHeight();
- return pos;
- });
- }
- }
- void OnDisable() {
- mScreenRayRaycasterUIWrapper.PressUp();
- }
- void OnEnable() {
- MakeMouseToScreenCenter();
- }
- void Update() {
- mScreenRayRaycasterUIWrapper.Update();
- }
-
- Vector2 ClampValue(Vector2 val)
- {
- val.x = val.x < 0 ? 0 : val.x;
- val.y = val.y < 0 ? 0 : val.y;
- float maxWidth = GetScaleScreenWidth();
- float maxHeight = GetScaleScreenHeight();
- val.x = val.x > maxWidth ? maxWidth : val.x;
- val.y = val.y > maxHeight ? maxHeight : val.y;
-
- return val;
- }
- #region 对外提供的接口
- public float GetScaleScreenWidth() {
- float width = Screen.width;
- if (canvasScaler.uiScaleMode == CanvasScaler.ScaleMode.ScaleWithScreenSize) {
- if (canvasScaler.screenMatchMode == CanvasScaler.ScreenMatchMode.MatchWidthOrHeight) {
- float height = Screen.height;
- if (canvasScaler.matchWidthOrHeight == 1) {
- width *= canvasScaler.referenceResolution.y / height;
- } else if (canvasScaler.matchWidthOrHeight == 0) {
- width = canvasScaler.referenceResolution.x;
- }
- }
- }
- return width;
- }
- public float GetScaleScreenHeight() {
- float height = Screen.height;
- if (canvasScaler.uiScaleMode == CanvasScaler.ScaleMode.ScaleWithScreenSize) {
- if (canvasScaler.screenMatchMode == CanvasScaler.ScreenMatchMode.MatchWidthOrHeight) {
- float width = Screen.width;
- if (canvasScaler.matchWidthOrHeight == 0) {
- height *= canvasScaler.referenceResolution.x / width;
- } else if (canvasScaler.matchWidthOrHeight == 1) {
- height = canvasScaler.referenceResolution.y;
- }
- }
- }
- return height;
- }
- public void MoveMousePointer(Vector2 deltaPos)
- {
- if (mousePointer == null) return;
- Vector2 val = mousePointer.anchoredPosition;
- val += deltaPos;
- mousePointer.anchoredPosition = ClampValue(val);
- }
- public void SetMousePointerPosition(Vector2 pos)
- {
- if (mousePointer == null) return;
- mousePointer.position = pos;
- }
- public void ClickMousePointer()
- {
- mScreenRayRaycasterUIWrapper.Click();
- }
- public void MakeMouseToScreenCenter() {
- mousePointer.anchoredPosition = new Vector2(GetScaleScreenWidth()/2,GetScaleScreenHeight()/2);
- }
- public Selectable GetCurrentSelectable() {
- return mScreenRayRaycasterUIWrapper.m_currentSelectable;
- }
- public void onSetNullToSelectable(Selectable target)
- {
- //mScreenRayRaycasterUIWrapper.OnSelect(target);
- }
- #endregion 对外提供的接口
- }
- public class ScreenRayRaycasterUIWrapper
- {
- public Selectable m_currentSelectable = null;
- RaycastResult m_currentRaycastResult;
-
- IPointerClickHandler m_clickHandler;
- IDragHandler m_dragHandler;
-
- EventSystem m_eventSystem;
- PointerEventData m_pointerEvent;
- SimulateMouse mSimulateMouse;
- Func<Vector2> mFunPointerPos;
- private bool mIsClick = false;
- private bool mIsPress = false;
- private bool mIsDrag = false;
-
- public void Init(SimulateMouse simulateMouse, Func<Vector2> funPointerPos)
- {
- mSimulateMouse = simulateMouse;
- m_eventSystem = EventSystem.current;
- m_pointerEvent = new PointerEventData(m_eventSystem);
- m_pointerEvent.button = PointerEventData.InputButton.Left;
- mFunPointerPos = funPointerPos;
- }
-
- public void Update()
- {
- m_pointerEvent.position = mFunPointerPos.Invoke();
-
- List<RaycastResult> raycastResults = new List<RaycastResult>();
- m_eventSystem.RaycastAll(m_pointerEvent, raycastResults);
-
- // Detect selectable
- bool hasRaycastSelectable = false;
-
- if (raycastResults.Count > 0)
- {
- var result = raycastResults[0]; //只检测第一个
- var newSelectable = result.gameObject.GetComponentInParent<Selectable>();
- if (newSelectable)
- {
- hasRaycastSelectable = true;
- if (newSelectable != m_currentSelectable)
- {
- Select(newSelectable);
- m_currentRaycastResult = result;
- }
- }
- }
- if (!hasRaycastSelectable)
- {
- if (m_currentSelectable)
- {
- Select(null);
- }
- }
-
- if (m_currentSelectable)
- {
- if (m_clickHandler != null && mIsClick)
- {
- try { mSimulateMouse.OnPointerClick?.Invoke(m_currentSelectable); }
- catch (System.Exception e) { Debug.LogError(e.Message); }
- m_clickHandler.OnPointerClick(m_pointerEvent);
- Select(null);
- }
- else if (m_dragHandler != null && mIsPress)
- {
- mIsDrag = true;
- m_pointerEvent.pointerPressRaycast = m_currentRaycastResult;
- m_dragHandler.OnDrag(m_pointerEvent);
- }
- }
- mIsClick = false;
- }
- public void OnSelect(Selectable s) {
- Select(s);
- }
- void Select(Selectable s)
- {
- if (mIsDrag == true) return;
-
- // if (m_currentSelectable) { //退出选中
- // m_currentSelectable.OnPointerExit(m_pointerEvent);
- // }
- m_currentSelectable = s;
-
- if (m_currentSelectable) {
- try { mSimulateMouse.OnPointerEnter?.Invoke(m_currentSelectable); }
- catch (System.Exception e) { Debug.LogError(e.Message); Debug.LogError(e.StackTrace); }
- // m_currentSelectable.OnPointerEnter(m_pointerEvent); //选中
- m_clickHandler = m_currentSelectable.GetComponent<IPointerClickHandler>();
- m_dragHandler = m_currentSelectable.GetComponent<IDragHandler>();
- } else {
- m_clickHandler = null;
- m_dragHandler = null;
- }
- }
- //模拟点击
- public void Click() {
- mIsClick = true;
- }
- //模拟按下
- public void PressDown() {
- mIsClick = true;
- mIsPress = true;
- mIsDrag = false;
- }
- //模拟松开
- public void PressUp() {
- mIsClick = false;
- mIsPress = false;
- mIsDrag = false;
- Select(null);
- }
- }
- }
|