Created
July 27, 2016 20:11
-
-
Save ousttrue/9019da47e8412b25f2ab1d32eb1cc21d to your computer and use it in GitHub Desktop.
InputModule for Unity5.3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using UnityEngine; | |
using UnityEngine.Serialization; | |
using UnityEngine.EventSystems; | |
using System.Collections.Generic; | |
using System.Text; | |
namespace CustomInput | |
{ | |
[AddComponentMenu("Event/Integrated Standalone Input Module")] | |
public class IntegratedStandaloneInputModule53 : BaseInputModule | |
{ | |
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(); | |
} | |
#region PointerInputModule | |
public const int kMouseLeftId = -1; | |
public const int kMouseRightId = -2; | |
public const int kMouseMiddleId = -3; | |
public const int kFakeTouchesId = -4; | |
Dictionary<int, PointerEventData> m_PointerData = new Dictionary<int, PointerEventData>(); | |
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; | |
} | |
void RemovePointerData(PointerEventData data) | |
{ | |
m_PointerData.Remove(data.pointerId); | |
} | |
PointerEventData GetTouchPointerEventData(Touch input, out bool pressed, out bool released) | |
{ | |
PointerEventData pointerData; | |
var created = GetPointerData(input.fingerId, out pointerData, true); | |
pointerData.Reset(); | |
pressed = created || (input.phase == TouchPhase.Began); | |
released = (input.phase == TouchPhase.Canceled) || (input.phase == TouchPhase.Ended); | |
if (created) | |
pointerData.position = input.position; | |
if (pressed) | |
pointerData.delta = Vector2.zero; | |
else | |
pointerData.delta = input.position - pointerData.position; | |
pointerData.position = input.position; | |
pointerData.button = PointerEventData.InputButton.Left; | |
eventSystem.RaycastAll(pointerData, m_RaycastResultCache); | |
var raycast = FindFirstRaycast(m_RaycastResultCache); | |
pointerData.pointerCurrentRaycast = raycast; | |
m_RaycastResultCache.Clear(); | |
return pointerData; | |
} | |
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; | |
} | |
static 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; | |
} | |
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; | |
} | |
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(); | |
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; | |
leftData.delta = pos - leftData.position; | |
leftData.position = pos; | |
leftData.scrollDelta = Input.mouseScrollDelta; | |
leftData.button = PointerEventData.InputButton.Left; | |
eventSystem.RaycastAll(leftData, m_RaycastResultCache); | |
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; | |
} | |
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; | |
} | |
void ProcessMove(PointerEventData pointerEvent) | |
{ | |
var targetGO = pointerEvent.pointerCurrentRaycast.gameObject; | |
HandlePointerExitAndEnter(pointerEvent, targetGO); | |
} | |
void ProcessDrag(PointerEventData pointerEvent) | |
{ | |
bool moving = pointerEvent.IsPointerMoving(); | |
if (moving && pointerEvent.pointerDrag != null | |
&& !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 && moving && pointerEvent.pointerDrag != null) | |
{ | |
// 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; | |
} | |
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); | |
} | |
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); | |
} | |
#endregion | |
#region StandaloneInputModule | |
private float m_PrevActionTime; | |
private Vector2 m_LastMoveVector; | |
private int m_ConsecutiveMoveCount = 0; | |
private Vector2 m_LastMousePosition; | |
private Vector2 m_MousePosition; | |
[SerializeField] | |
private string m_HorizontalAxis = "Horizontal"; | |
/// <summary> | |
/// Name of the vertical axis for movement (if axis events are used). | |
/// </summary> | |
[SerializeField] | |
private string m_VerticalAxis = "Vertical"; | |
/// <summary> | |
/// Name of the submit button. | |
/// </summary> | |
[SerializeField] | |
private string m_SubmitButton = "Submit"; | |
/// <summary> | |
/// Name of the submit button. | |
/// </summary> | |
[SerializeField] | |
private string m_CancelButton = "Cancel"; | |
[SerializeField] | |
private float m_InputActionsPerSecond = 10; | |
[SerializeField] | |
private float m_RepeatDelay = 0.5f; | |
[SerializeField] | |
[FormerlySerializedAs("m_AllowActivationOnMobileDevice")] | |
private bool m_ForceModuleActive; | |
[Obsolete("allowActivationOnMobileDevice has been deprecated. Use forceModuleActive instead (UnityUpgradable) -> forceModuleActive")] | |
public bool allowActivationOnMobileDevice | |
{ | |
get { return m_ForceModuleActive; } | |
set { m_ForceModuleActive = value; } | |
} | |
public bool forceModuleActive | |
{ | |
get { return m_ForceModuleActive; } | |
set { m_ForceModuleActive = value; } | |
} | |
public float inputActionsPerSecond | |
{ | |
get { return m_InputActionsPerSecond; } | |
set { m_InputActionsPerSecond = value; } | |
} | |
public float repeatDelay | |
{ | |
get { return m_RepeatDelay; } | |
set { m_RepeatDelay = value; } | |
} | |
/// <summary> | |
/// Name of the horizontal axis for movement (if axis events are used). | |
/// </summary> | |
public string horizontalAxis | |
{ | |
get { return m_HorizontalAxis; } | |
set { m_HorizontalAxis = value; } | |
} | |
/// <summary> | |
/// Name of the vertical axis for movement (if axis events are used). | |
/// </summary> | |
public string verticalAxis | |
{ | |
get { return m_VerticalAxis; } | |
set { m_VerticalAxis = value; } | |
} | |
public string submitButton | |
{ | |
get { return m_SubmitButton; } | |
set { m_SubmitButton = value; } | |
} | |
public string cancelButton | |
{ | |
get { return m_CancelButton; } | |
set { m_CancelButton = value; } | |
} | |
public override void UpdateModule() | |
{ | |
m_LastMousePosition = m_MousePosition; | |
m_MousePosition = Input.mousePosition; | |
} | |
public override bool IsModuleSupported() | |
{ | |
return m_ForceModuleActive || Input.mousePresent || Input.touchSupported; | |
} | |
public override bool ShouldActivateModule() | |
{ | |
if (!base.ShouldActivateModule()) | |
return false; | |
var shouldActivate = m_ForceModuleActive; | |
shouldActivate |= Input.GetButtonDown(m_SubmitButton); | |
shouldActivate |= Input.GetButtonDown(m_CancelButton); | |
shouldActivate |= !Mathf.Approximately(Input.GetAxisRaw(m_HorizontalAxis), 0.0f); | |
shouldActivate |= !Mathf.Approximately(Input.GetAxisRaw(m_VerticalAxis), 0.0f); | |
shouldActivate |= (m_MousePosition - m_LastMousePosition).sqrMagnitude > 0.0f; | |
shouldActivate |= Input.GetMouseButtonDown(0); | |
for (int i = 0; i < Input.touchCount; ++i) | |
{ | |
Touch input = Input.GetTouch(i); | |
shouldActivate |= input.phase == TouchPhase.Began | |
|| input.phase == TouchPhase.Moved | |
|| input.phase == TouchPhase.Stationary; | |
} | |
return shouldActivate; | |
} | |
public override void ActivateModule() | |
{ | |
base.ActivateModule(); | |
m_MousePosition = Input.mousePosition; | |
m_LastMousePosition = Input.mousePosition; | |
var toSelect = eventSystem.currentSelectedGameObject; | |
if (toSelect == null) | |
toSelect = eventSystem.firstSelectedGameObject; | |
eventSystem.SetSelectedGameObject(toSelect, GetBaseEventData()); | |
} | |
public override void DeactivateModule() | |
{ | |
base.DeactivateModule(); | |
ClearSelection(); | |
} | |
public override void Process() | |
{ | |
bool usedEvent = SendUpdateEventToSelectedObject(); | |
if (eventSystem.sendNavigationEvents) | |
{ | |
if (!usedEvent) | |
usedEvent |= SendMoveEventToSelectedObject(); | |
if (!usedEvent) | |
SendSubmitEventToSelectedObject(); | |
} | |
// touch needs to take precedence because of the mouse emulation layer | |
if (!ProcessTouchEvents()) | |
ProcessMouseEvent(0); | |
} | |
private bool ProcessTouchEvents() | |
{ | |
for (int i = 0; i < Input.touchCount; ++i) | |
{ | |
Touch input = Input.GetTouch(i); | |
if (input.type == TouchType.Indirect) | |
continue; | |
bool released; | |
bool pressed; | |
var pointer = GetTouchPointerEventData(input, out pressed, out released); | |
ProcessTouchPress(pointer, pressed, released); | |
if (!released) | |
{ | |
ProcessMove(pointer); | |
ProcessDrag(pointer); | |
} | |
else | |
RemovePointerData(pointer); | |
} | |
return Input.touchCount > 0; | |
} | |
private void ProcessTouchPress(PointerEventData pointerEvent, bool pressed, bool released) | |
{ | |
var currentOverGo = pointerEvent.pointerCurrentRaycast.gameObject; | |
// PointerDown notification | |
if (pressed) | |
{ | |
pointerEvent.eligibleForClick = true; | |
pointerEvent.delta = Vector2.zero; | |
pointerEvent.dragging = false; | |
pointerEvent.useDragThreshold = true; | |
pointerEvent.pressPosition = pointerEvent.position; | |
pointerEvent.pointerPressRaycast = pointerEvent.pointerCurrentRaycast; | |
DeselectIfSelectionChanged(currentOverGo, pointerEvent); | |
if (pointerEvent.pointerEnter != currentOverGo) | |
{ | |
// send a pointer enter to the touched element if it isn't the one to select... | |
HandlePointerExitAndEnter(pointerEvent, currentOverGo); | |
pointerEvent.pointerEnter = currentOverGo; | |
} | |
// search for the control that will receive the press | |
// if we can't find a press handler set the press | |
// handler to be what would receive a click. | |
var newPressed = ExecuteEvents.ExecuteHierarchy(currentOverGo, pointerEvent, ExecuteEvents.pointerDownHandler); | |
// didnt find a press handler... search for a click handler | |
if (newPressed == null) | |
newPressed = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo); | |
// Debug.Log("Pressed: " + newPressed); | |
float time = Time.unscaledTime; | |
if (newPressed == pointerEvent.lastPress) | |
{ | |
var diffTime = time - pointerEvent.clickTime; | |
if (diffTime < 0.3f) | |
++pointerEvent.clickCount; | |
else | |
pointerEvent.clickCount = 1; | |
pointerEvent.clickTime = time; | |
} | |
else | |
{ | |
pointerEvent.clickCount = 1; | |
} | |
pointerEvent.pointerPress = newPressed; | |
pointerEvent.rawPointerPress = currentOverGo; | |
pointerEvent.clickTime = time; | |
// Save the drag handler as well | |
pointerEvent.pointerDrag = ExecuteEvents.GetEventHandler<IDragHandler>(currentOverGo); | |
if (pointerEvent.pointerDrag != null) | |
ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.initializePotentialDrag); | |
} | |
// PointerUp notification | |
if (released) | |
{ | |
// Debug.Log("Executing pressup on: " + pointer.pointerPress); | |
ExecuteEvents.Execute(pointerEvent.pointerPress, pointerEvent, ExecuteEvents.pointerUpHandler); | |
// Debug.Log("KeyCode: " + pointer.eventData.keyCode); | |
// see if we mouse up on the same element that we clicked on... | |
var pointerUpHandler = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo); | |
// PointerClick and Drop events | |
if (pointerEvent.pointerPress == pointerUpHandler && pointerEvent.eligibleForClick) | |
{ | |
ExecuteEvents.Execute(pointerEvent.pointerPress, pointerEvent, ExecuteEvents.pointerClickHandler); | |
} | |
else if (pointerEvent.pointerDrag != null && pointerEvent.dragging) | |
{ | |
ExecuteEvents.ExecuteHierarchy(currentOverGo, pointerEvent, ExecuteEvents.dropHandler); | |
} | |
pointerEvent.eligibleForClick = false; | |
pointerEvent.pointerPress = null; | |
pointerEvent.rawPointerPress = null; | |
if (pointerEvent.pointerDrag != null && pointerEvent.dragging) | |
ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.endDragHandler); | |
pointerEvent.dragging = false; | |
pointerEvent.pointerDrag = null; | |
if (pointerEvent.pointerDrag != null) | |
ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.endDragHandler); | |
pointerEvent.pointerDrag = null; | |
// send exit events as we need to simulate this on touch up on touch device | |
ExecuteEvents.ExecuteHierarchy(pointerEvent.pointerEnter, pointerEvent, ExecuteEvents.pointerExitHandler); | |
pointerEvent.pointerEnter = null; | |
} | |
} | |
/// <summary> | |
/// Process submit keys. | |
/// </summary> | |
bool SendSubmitEventToSelectedObject() | |
{ | |
if (eventSystem.currentSelectedGameObject == null) | |
return false; | |
var data = GetBaseEventData(); | |
if (Input.GetButtonDown(m_SubmitButton)) | |
ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, data, ExecuteEvents.submitHandler); | |
if (Input.GetButtonDown(m_CancelButton)) | |
ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, data, ExecuteEvents.cancelHandler); | |
return data.used; | |
} | |
private Vector2 GetRawMoveVector() | |
{ | |
Vector2 move = Vector2.zero; | |
move.x = Input.GetAxisRaw(m_HorizontalAxis); | |
move.y = Input.GetAxisRaw(m_VerticalAxis); | |
if (Input.GetButtonDown(m_HorizontalAxis)) | |
{ | |
if (move.x < 0) | |
move.x = -1f; | |
if (move.x > 0) | |
move.x = 1f; | |
} | |
if (Input.GetButtonDown(m_VerticalAxis)) | |
{ | |
if (move.y < 0) | |
move.y = -1f; | |
if (move.y > 0) | |
move.y = 1f; | |
} | |
return move; | |
} | |
/// <summary> | |
/// Process keyboard events. | |
/// </summary> | |
bool SendMoveEventToSelectedObject() | |
{ | |
float time = Time.unscaledTime; | |
Vector2 movement = GetRawMoveVector(); | |
if (Mathf.Approximately(movement.x, 0f) && Mathf.Approximately(movement.y, 0f)) | |
{ | |
m_ConsecutiveMoveCount = 0; | |
return false; | |
} | |
// If user pressed key again, always allow event | |
bool allow = Input.GetButtonDown(m_HorizontalAxis) || Input.GetButtonDown(m_VerticalAxis); | |
bool similarDir = (Vector2.Dot(movement, m_LastMoveVector) > 0); | |
if (!allow) | |
{ | |
// Otherwise, user held down key or axis. | |
// If direction didn't change at least 90 degrees, wait for delay before allowing consequtive event. | |
if (similarDir && m_ConsecutiveMoveCount == 1) | |
allow = (time > m_PrevActionTime + m_RepeatDelay); | |
// If direction changed at least 90 degree, or we already had the delay, repeat at repeat rate. | |
else | |
allow = (time > m_PrevActionTime + 1f / m_InputActionsPerSecond); | |
} | |
if (!allow) | |
return false; | |
// Debug.Log(m_ProcessingEvent.rawType + " axis:" + m_AllowAxisEvents + " value:" + "(" + x + "," + y + ")"); | |
var axisEventData = GetAxisEventData(movement.x, movement.y, 0.6f); | |
if (axisEventData.moveDir != MoveDirection.None) | |
{ | |
ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, axisEventData, ExecuteEvents.moveHandler); | |
if (!similarDir) | |
m_ConsecutiveMoveCount = 0; | |
m_ConsecutiveMoveCount++; | |
m_PrevActionTime = time; | |
m_LastMoveVector = movement; | |
} | |
else | |
{ | |
m_ConsecutiveMoveCount = 0; | |
} | |
return axisEventData.used; | |
} | |
/// <summary> | |
/// Process all mouse events. | |
/// </summary> | |
void ProcessMouseEvent(int id) | |
{ | |
var mouseData = GetMousePointerEventData(id); | |
var leftButtonData = mouseData.GetButtonState(PointerEventData.InputButton.Left).eventData; | |
// Process the first mouse button fully | |
ProcessMousePress(leftButtonData); | |
ProcessMove(leftButtonData.buttonData); | |
ProcessDrag(leftButtonData.buttonData); | |
// Now process right / middle clicks | |
ProcessMousePress(mouseData.GetButtonState(PointerEventData.InputButton.Right).eventData); | |
ProcessDrag(mouseData.GetButtonState(PointerEventData.InputButton.Right).eventData.buttonData); | |
ProcessMousePress(mouseData.GetButtonState(PointerEventData.InputButton.Middle).eventData); | |
ProcessDrag(mouseData.GetButtonState(PointerEventData.InputButton.Middle).eventData.buttonData); | |
if (!Mathf.Approximately(leftButtonData.buttonData.scrollDelta.sqrMagnitude, 0.0f)) | |
{ | |
var scrollHandler = ExecuteEvents.GetEventHandler<IScrollHandler>(leftButtonData.buttonData.pointerCurrentRaycast.gameObject); | |
ExecuteEvents.ExecuteHierarchy(scrollHandler, leftButtonData.buttonData, ExecuteEvents.scrollHandler); | |
} | |
} | |
bool SendUpdateEventToSelectedObject() | |
{ | |
if (eventSystem.currentSelectedGameObject == null) | |
return false; | |
var data = GetBaseEventData(); | |
ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, data, ExecuteEvents.updateSelectedHandler); | |
return data.used; | |
} | |
/// <summary> | |
/// Process the current mouse press. | |
/// </summary> | |
void ProcessMousePress(MouseButtonEventData data) | |
{ | |
var pointerEvent = data.buttonData; | |
var currentOverGo = pointerEvent.pointerCurrentRaycast.gameObject; | |
// PointerDown notification | |
if (data.PressedThisFrame()) | |
{ | |
pointerEvent.eligibleForClick = true; | |
pointerEvent.delta = Vector2.zero; | |
pointerEvent.dragging = false; | |
pointerEvent.useDragThreshold = true; | |
pointerEvent.pressPosition = pointerEvent.position; | |
pointerEvent.pointerPressRaycast = pointerEvent.pointerCurrentRaycast; | |
DeselectIfSelectionChanged(currentOverGo, pointerEvent); | |
// search for the control that will receive the press | |
// if we can't find a press handler set the press | |
// handler to be what would receive a click. | |
var newPressed = ExecuteEvents.ExecuteHierarchy(currentOverGo, pointerEvent, ExecuteEvents.pointerDownHandler); | |
// didnt find a press handler... search for a click handler | |
if (newPressed == null) | |
newPressed = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo); | |
// Debug.Log("Pressed: " + newPressed); | |
float time = Time.unscaledTime; | |
if (newPressed == pointerEvent.lastPress) | |
{ | |
var diffTime = time - pointerEvent.clickTime; | |
if (diffTime < 0.3f) | |
++pointerEvent.clickCount; | |
else | |
pointerEvent.clickCount = 1; | |
pointerEvent.clickTime = time; | |
} | |
else | |
{ | |
pointerEvent.clickCount = 1; | |
} | |
pointerEvent.pointerPress = newPressed; | |
pointerEvent.rawPointerPress = currentOverGo; | |
pointerEvent.clickTime = time; | |
// Save the drag handler as well | |
pointerEvent.pointerDrag = ExecuteEvents.GetEventHandler<IDragHandler>(currentOverGo); | |
if (pointerEvent.pointerDrag != null) | |
ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.initializePotentialDrag); | |
} | |
// PointerUp notification | |
if (data.ReleasedThisFrame()) | |
{ | |
// Debug.Log("Executing pressup on: " + pointer.pointerPress); | |
ExecuteEvents.Execute(pointerEvent.pointerPress, pointerEvent, ExecuteEvents.pointerUpHandler); | |
// Debug.Log("KeyCode: " + pointer.eventData.keyCode); | |
// see if we mouse up on the same element that we clicked on... | |
var pointerUpHandler = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo); | |
// PointerClick and Drop events | |
if (pointerEvent.pointerPress == pointerUpHandler && pointerEvent.eligibleForClick) | |
{ | |
ExecuteEvents.Execute(pointerEvent.pointerPress, pointerEvent, ExecuteEvents.pointerClickHandler); | |
} | |
else if (pointerEvent.pointerDrag != null && pointerEvent.dragging) | |
{ | |
ExecuteEvents.ExecuteHierarchy(currentOverGo, pointerEvent, ExecuteEvents.dropHandler); | |
} | |
pointerEvent.eligibleForClick = false; | |
pointerEvent.pointerPress = null; | |
pointerEvent.rawPointerPress = null; | |
if (pointerEvent.pointerDrag != null && pointerEvent.dragging) | |
ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.endDragHandler); | |
pointerEvent.dragging = false; | |
pointerEvent.pointerDrag = null; | |
// redo pointer enter / exit to refresh state | |
// so that if we moused over somethign that ignored it before | |
// due to having pressed on something else | |
// it now gets it. | |
if (currentOverGo != pointerEvent.pointerEnter) | |
{ | |
HandlePointerExitAndEnter(pointerEvent, null); | |
HandlePointerExitAndEnter(pointerEvent, currentOverGo); | |
} | |
} | |
} | |
#endregion | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment