diff options
author | chai <chaifix@163.com> | 2021-05-08 23:15:13 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2021-05-08 23:15:13 +0800 |
commit | d07e14add74e017b52ab2371efeea1aa4ea10ced (patch) | |
tree | efd07869326e4c428f5bfe43fad0c2583d32a401 /Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/PointerInputModule.cs |
+init
Diffstat (limited to 'Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/PointerInputModule.cs')
-rw-r--r-- | Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/PointerInputModule.cs | 342 |
1 files changed, 342 insertions, 0 deletions
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/PointerInputModule.cs b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/PointerInputModule.cs new file mode 100644 index 0000000..3aa8e09 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/PointerInputModule.cs @@ -0,0 +1,342 @@ +using System.Collections.Generic; +using System.Text; +using UnityEngine.UI; + +namespace UnityEngine.EventSystems +{ + + // 会处理触屏和鼠标 + public abstract class PointerInputModule : BaseInputModule + { + public const int kMouseLeftId = -1; + public const int kMouseRightId = -2; + public const int kMouseMiddleId = -3; + + public const int kFakeTouchesId = -4; + + // 一个池子 + protected Dictionary<int, PointerEventData> m_PointerData = new Dictionary<int, PointerEventData>(); + + protected bool GetPointerData(int id, out PointerEventData data, bool create) + { + if (!m_PointerData.TryGetValue(id, out data) && create) // 一个池子 + { + data = new PointerEventData(eventSystem) + { + pointerId = id, + }; + m_PointerData.Add(id, data); + return true; + } + return false; + } + + protected void RemovePointerData(PointerEventData data) + { + m_PointerData.Remove(data.pointerId); + } + + //c 根据touch数据得到pointEventData,并且保存raycaster结果 + protected PointerEventData GetTouchPointerEventData(Touch input, out bool pressed, out bool released) + { + PointerEventData pointerData; + // 从池子里拿到存储结构,返回是否是新建结构 + var created = GetPointerData(input.fingerId, out pointerData, true); + + pointerData.Reset(); + + // pressed和released用来判断抬起或者放下 + + pressed = created || (input.phase == TouchPhase.Began); // 如果结构是新建的或input phase是bagan,说明是刚按下 + released = (input.phase == TouchPhase.Canceled) || (input.phase == TouchPhase.Ended); // 如果phase是这两种,说明是抬起来了 + + if (created)//如果是新建的,记录下起始位置,否则还保留旧值,下面用来计算delta + pointerData.position = input.position; + + if (pressed)//如果是刚按下,delta置为0 + pointerData.delta = Vector2.zero; + else + pointerData.delta = input.position - pointerData.position; // 计算delta + + pointerData.position = input.position; // 计算完delta后覆盖 + + pointerData.button = PointerEventData.InputButton.Left; // 这里不知道为什么 + + // 用这个触摸数据做射线检测,检测结果在m_RaycastResultCache + eventSystem.RaycastAll(pointerData, m_RaycastResultCache); + + // 只取第一个,舍弃其他的 + var raycast = FindFirstRaycast(m_RaycastResultCache); + Debug.Log("raycast: " + raycast.index); + pointerData.pointerCurrentRaycast = raycast; + m_RaycastResultCache.Clear(); + return pointerData; + } + + protected void CopyFromTo(PointerEventData @from, PointerEventData @to) + { + @to.position = @from.position; + @to.delta = @from.delta; + @to.scrollDelta = @from.scrollDelta; + @to.pointerCurrentRaycast = @from.pointerCurrentRaycast; + @to.pointerEnter = @from.pointerEnter; + } + + protected PointerEventData.FramePressState StateForMouseButton(int buttonId) + { + var pressed = input.GetMouseButtonDown(buttonId); + var released = input.GetMouseButtonUp(buttonId); + if (pressed && released) + return PointerEventData.FramePressState.PressedAndReleased; + if (pressed) + return PointerEventData.FramePressState.Pressed; + if (released) + return PointerEventData.FramePressState.Released; + return PointerEventData.FramePressState.NotChanged; + } + + protected class ButtonState + { + private PointerEventData.InputButton m_Button = PointerEventData.InputButton.Left; + + public MouseButtonEventData eventData + { + get { return m_EventData; } + set { m_EventData = value; } + } + + public PointerEventData.InputButton button + { + get { return m_Button; } + set { m_Button = value; } + } + + private MouseButtonEventData m_EventData; + } + + protected class MouseState + { + private List<ButtonState> m_TrackedButtons = new List<ButtonState>(); + + public bool AnyPressesThisFrame() + { + for (int i = 0; i < m_TrackedButtons.Count; i++) + { + if (m_TrackedButtons[i].eventData.PressedThisFrame()) + return true; + } + return false; + } + + public bool AnyReleasesThisFrame() + { + for (int i = 0; i < m_TrackedButtons.Count; i++) + { + if (m_TrackedButtons[i].eventData.ReleasedThisFrame()) + return true; + } + return false; + } + + public ButtonState GetButtonState(PointerEventData.InputButton button) + { + ButtonState tracked = null; + for (int i = 0; i < m_TrackedButtons.Count; i++) + { + if (m_TrackedButtons[i].button == button) + { + tracked = m_TrackedButtons[i]; + break; + } + } + + if (tracked == null) + { + tracked = new ButtonState { button = button, eventData = new MouseButtonEventData() }; + m_TrackedButtons.Add(tracked); + } + return tracked; + } + + public void SetButtonState(PointerEventData.InputButton button, PointerEventData.FramePressState stateForMouseButton, PointerEventData data) + { + var toModify = GetButtonState(button); + toModify.eventData.buttonState = stateForMouseButton; + toModify.eventData.buttonData = data; + } + } + + public class MouseButtonEventData + { + public PointerEventData.FramePressState buttonState; + public PointerEventData buttonData; + + public bool PressedThisFrame() + { + return buttonState == PointerEventData.FramePressState.Pressed || buttonState == PointerEventData.FramePressState.PressedAndReleased; + } + + public bool ReleasedThisFrame() + { + return buttonState == PointerEventData.FramePressState.Released || buttonState == PointerEventData.FramePressState.PressedAndReleased; + } + } + + private readonly MouseState m_MouseState = new MouseState(); + + protected virtual MouseState GetMousePointerEventData() + { + return GetMousePointerEventData(0); + } + + protected virtual MouseState GetMousePointerEventData(int id) + { + // Populate the left button... + PointerEventData leftData; + var created = GetPointerData(kMouseLeftId, out leftData, true); + + leftData.Reset(); + + if (created) + leftData.position = input.mousePosition; + + Vector2 pos = input.mousePosition; + if (Cursor.lockState == CursorLockMode.Locked) + { + // We don't want to do ANY cursor-based interaction when the mouse is locked + leftData.position = new Vector2(-1.0f, -1.0f); + leftData.delta = Vector2.zero; + } + else + { + leftData.delta = pos - leftData.position; + leftData.position = pos; + } + leftData.scrollDelta = input.mouseScrollDelta; + leftData.button = PointerEventData.InputButton.Left; + eventSystem.RaycastAll(leftData, m_RaycastResultCache); + + // 只要第一个raycast结果 + var raycast = FindFirstRaycast(m_RaycastResultCache); + leftData.pointerCurrentRaycast = raycast; + m_RaycastResultCache.Clear(); + + // copy the apropriate data into right and middle slots + PointerEventData rightData; + GetPointerData(kMouseRightId, out rightData, true); + CopyFromTo(leftData, rightData); + rightData.button = PointerEventData.InputButton.Right; + + PointerEventData middleData; + GetPointerData(kMouseMiddleId, out middleData, true); + CopyFromTo(leftData, middleData); + middleData.button = PointerEventData.InputButton.Middle; + + // 设置按键状态 + m_MouseState.SetButtonState(PointerEventData.InputButton.Left, StateForMouseButton(0), leftData); + m_MouseState.SetButtonState(PointerEventData.InputButton.Right, StateForMouseButton(1), rightData); + m_MouseState.SetButtonState(PointerEventData.InputButton.Middle, StateForMouseButton(2), middleData); + + return m_MouseState; + } + + protected PointerEventData GetLastPointerEventData(int id) + { + PointerEventData data; + GetPointerData(id, out data, false); + return data; + } + + private static bool ShouldStartDrag(Vector2 pressPos, Vector2 currentPos, float threshold, bool useDragThreshold) + { + if (!useDragThreshold) + return true; + + return (pressPos - currentPos).sqrMagnitude >= threshold * threshold; + } + + protected virtual void ProcessMove(PointerEventData pointerEvent) + { + var targetGO = (Cursor.lockState == CursorLockMode.Locked ? null : pointerEvent.pointerCurrentRaycast.gameObject); + HandlePointerExitAndEnter(pointerEvent, targetGO); + } + + // 发送drag事件 + protected virtual void ProcessDrag(PointerEventData pointerEvent) + { + if (!pointerEvent.IsPointerMoving() || + Cursor.lockState == CursorLockMode.Locked || + pointerEvent.pointerDrag == null) + return; + + if (!pointerEvent.dragging + && ShouldStartDrag(pointerEvent.pressPosition, pointerEvent.position, eventSystem.pixelDragThreshold, pointerEvent.useDragThreshold)) + { + ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.beginDragHandler); + pointerEvent.dragging = true; + } + + // Drag notification + if (pointerEvent.dragging) + { + // Before doing drag we should cancel any pointer down state + // And clear selection! + if (pointerEvent.pointerPress != pointerEvent.pointerDrag) + { + ExecuteEvents.Execute(pointerEvent.pointerPress, pointerEvent, ExecuteEvents.pointerUpHandler); + + pointerEvent.eligibleForClick = false; + pointerEvent.pointerPress = null; + pointerEvent.rawPointerPress = null; + } + ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.dragHandler); + } + } + + public override bool IsPointerOverGameObject(int pointerId) + { + var lastPointer = GetLastPointerEventData(pointerId); + if (lastPointer != null) + return lastPointer.pointerEnter != null; + return false; + } + + protected void ClearSelection() + { + var baseEventData = GetBaseEventData(); + + foreach (var pointer in m_PointerData.Values) + { + // clear all selection + HandlePointerExitAndEnter(pointer, null); + } + + m_PointerData.Clear(); + eventSystem.SetSelectedGameObject(null, baseEventData); + } + + public override string ToString() + { + var sb = new StringBuilder("<b>Pointer Input Module of type: </b>" + GetType()); + sb.AppendLine(); + foreach (var pointer in m_PointerData) + { + if (pointer.Value == null) + continue; + sb.AppendLine("<B>Pointer:</b> " + pointer.Key); + sb.AppendLine(pointer.Value.ToString()); + } + return sb.ToString(); + } + + protected void DeselectIfSelectionChanged(GameObject currentOverGo, BaseEventData pointerEvent) + { + // Selection tracking + var selectHandlerGO = ExecuteEvents.GetEventHandler<ISelectHandler>(currentOverGo); + // if we have clicked something new, deselect the old thing + // leave 'selection handling' up to the press event though. + if (selectHandlerGO != eventSystem.currentSelectedGameObject) + eventSystem.SetSelectedGameObject(null, pointerEvent); + } + } +} |