Skip to content

Instantly share code, notes, and snippets.

@stramit
Created September 23, 2014 09:48
Show Gist options
  • Save stramit/b654082eb226492d9a04 to your computer and use it in GitHub Desktop.
Save stramit/b654082eb226492d9a04 to your computer and use it in GitHub Desktop.
TouchInputModule (b19)
using System.Text;
namespace UnityEngine.EventSystems
{
[AddComponentMenu("Event/Touch Input Module")]
public class TouchInputModule : PointerInputModule
{
protected TouchInputModule()
{}
private Vector2 m_LastMousePosition;
private Vector2 m_MousePosition;
[SerializeField]
private bool m_AllowActivationOnStandalone;
public bool allowActivationOnStandalone
{
get { return m_AllowActivationOnStandalone; }
set { m_AllowActivationOnStandalone = value; }
}
public override void UpdateModule()
{
m_LastMousePosition = m_MousePosition;
m_MousePosition = Input.mousePosition;
}
public override bool IsModuleSupported()
{
return m_AllowActivationOnStandalone || Application.isMobilePlatform;
}
public override bool ShouldActivateModule()
{
if (!base.ShouldActivateModule ())
return false;
if (UseFakeInput ())
{
bool wantsEnable = Input.GetMouseButtonDown (0);
wantsEnable |= (m_MousePosition - m_LastMousePosition).sqrMagnitude > 0.0f;
return wantsEnable;
}
for (int i = 0; i < Input.touchCount; ++i)
{
Touch input = Input.GetTouch (i);
if (input.phase == TouchPhase.Began
|| input.phase == TouchPhase.Moved
|| input.phase == TouchPhase.Stationary)
return true;
}
return false;
}
private bool UseFakeInput()
{
return !Application.isMobilePlatform;
}
public override void Process()
{
if (UseFakeInput ())
FakeTouches ();
else
ProcessTouchEvents ();
}
/// <summary>
/// For debugging touch-based devices using the mouse.
/// </summary>
private void FakeTouches()
{
bool pressed = Input.GetMouseButtonDown (0);
bool released = Input.GetMouseButtonUp (0);
var pointerData = GetMousePointerEventData ();
// fake touches... on press clear delta
if (pressed)
pointerData.delta = Vector2.zero;
ProcessTouchPress (pointerData, pressed, released);
// only process move if we are pressed...
if (Input.GetMouseButton (0))
ProcessMove (pointerData);
}
/// <summary>
/// Process all touch events.
/// </summary>
private void ProcessTouchEvents()
{
for (int i = 0; i < Input.touchCount; ++i)
{
Touch input = Input.GetTouch (i);
bool released;
bool pressed;
var pointer = GetTouchPointerEventData (input, out pressed, out released);
ProcessTouchPress (pointer, pressed, released);
if (!released)
ProcessMove (pointer);
else
RemovePointerData (pointer);
}
}
private void ProcessTouchPress(PointerEventData pointerEvent, bool pressed, bool released)
{
var currentOverGo = pointerEvent.pointerCurrentRaycast.go;
// PointerDown notification
if (pressed)
{
pointerEvent.eligibleForClick = true;
pointerEvent.delta = Vector2.zero;
pointerEvent.pressPosition = pointerEvent.position;
pointerEvent.pointerPressRaycast = pointerEvent.pointerCurrentRaycast;
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);
if (newPressed != pointerEvent.pointerPress)
{
pointerEvent.pointerPress = newPressed;
pointerEvent.rawPointerPress = currentOverGo;
pointerEvent.clickCount = 0;
}
// Save the drag handler as well
pointerEvent.pointerDrag = ExecuteEvents.GetEventHandler<IDragHandler> (currentOverGo);
if (pointerEvent.pointerDrag != null)
ExecuteEvents.Execute<IBeginDragHandler> (pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.beginDragHandler);
// Debug.Log("Setting Drag Handler to: " + pointer.pointerDrag);
// Selection tracking
var selectHandlerGO = ExecuteEvents.GetEventHandler<ISelectHandler> (currentOverGo);
eventSystem.SetSelectedGameObject (selectHandlerGO, pointerEvent);
}
// 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)
{
float time = Time.unscaledTime;
if (time - pointerEvent.clickTime < 0.3f)
++pointerEvent.clickCount;
else
pointerEvent.clickCount = 1;
pointerEvent.clickTime = time;
ExecuteEvents.Execute (pointerEvent.pointerPress, pointerEvent, ExecuteEvents.pointerClickHandler);
}
else if (pointerEvent.pointerDrag != null)
{
ExecuteEvents.ExecuteHierarchy (currentOverGo, pointerEvent, ExecuteEvents.dropHandler);
}
pointerEvent.eligibleForClick = false;
pointerEvent.pointerPress = null;
pointerEvent.rawPointerPress = 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;
}
}
public override void DeactivateModule()
{
base.DeactivateModule ();
ClearSelection ();
}
public override string ToString()
{
var sb = new StringBuilder ();
sb.AppendLine (UseFakeInput () ? "Input: Faked" : "Input: Touch");
if (UseFakeInput ())
{
var pointerData = GetLastPointerEventData (kMouseId);
if (pointerData != null)
sb.AppendLine (pointerData.ToString ());
}
else
{
foreach (var pointerEventData in m_PointerData)
sb.AppendLine (pointerEventData.ToString ());
}
return sb.ToString ();
}
}
}
@daniele-bondi
Copy link

@LumenDigital There's a GetPointerData implementation in PointerInputModule
https://gist.github.com/stramit/c98b992c43f7313084ac#file-pointerinputmodule-cs
That method is private so I guess someone could have changed it since b19

@flightCrazed
Copy link

flightCrazed commented Jun 26, 2020

Hi - I have just created my on VR input module through a process of trial and error then stumbled upon this. It would be great to be able to use this as a base for my module but I will need to override GetPointerData with my own method of raycasting. Would it be possible to see the source for the GetPointerData method so I can mirror its functionality?

I know the replay is 5 years old but I was in the same boat when I came across this. Hopefully this will help the next person:



private List<RaycastResult> raycastResults = new List<RaycastResult>();
        private bool isPressed;

             private void SetupEventData()
        {
            if (eventData == null)
                eventData = new PointerEventData(EventSystem.current);
            else
                eventData.Reset();

            eventData.delta = Vector2.zero;
            eventData.position = GetScreenCenter();
        }

        public override void Process()
        {

            SetupEventData();
            raycastResults.Clear();
            EventSystem.current.RaycastAll(eventData, raycastResults);

            eventData.pointerCurrentRaycast= FindFirstRaycast(raycastResults);

            HandlePointerExitAndEnter(eventData, eventData.pointerCurrentRaycast.gameObject);
            ProcessTouchPress(eventData, isPressed, !isPressed);     
        }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment