Hello.
I have just updated the module to include pinch and rotation. It is renamed to MultiTouchInputModule
Two interfaces IRotateHandler
and IPinchHandler
declare
public void OnRotate(RotateEventData data)
and
public void OnPinch(PinchEventData data)
In addition to the usual PointerEventData these classes have a pinchDelta and rotateDelta which are to be used like scrollDelta.
Hope this helps.
using UnityEngine;
using UnityEngine.EventSystems;
using System.Collections.Generic;
namespace UnityEngine.EventSystems
{
public class PinchEventData : BaseEventData
{
public List<PointerEventData> data;
public float pinchDelta;
public PinchEventData (EventSystem ES, float d = 0) : base (ES)
{
data = new List<PointerEventData> ();
pinchDelta = d;
}
}
public class RotateEventData : BaseEventData
{
public List<PointerEventData> data;
public float rotateDelta;
public RotateEventData (EventSystem ES, float d = 0) : base (ES)
{
data = new List<PointerEventData> ();
rotateDelta = d;
}
}
public interface IPinchHandler : IEventSystemHandler
{
void OnPinch (PinchEventData data);
}
public interface IRotateHandler : IEventSystemHandler
{
void OnRotate (RotateEventData data);
}
public static class MultiTouchModuleEvents
{
private static void Execute (IPinchHandler handler, BaseEventData eventData)
{
handler.OnPinch (ExecuteEvents.ValidateEventData<PinchEventData> (eventData));
}
private static void Execute (IRotateHandler handler, BaseEventData eventData)
{
handler.OnRotate (ExecuteEvents.ValidateEventData<RotateEventData> (eventData));
}
public static ExecuteEvents.EventFunction<IPinchHandler> pinchHandler {
get { return Execute; }
}
public static ExecuteEvents.EventFunction<IRotateHandler> rotateHandler {
get { return Execute; }
}
}
public class MultiTouchInputModule : PointerInputModule
{
private PinchEventData _pinchData;
private RotateEventData _rotateData;
private enum _MultiTouchMode
{
Idle, // no touch input.
Began, // 2 input touches received.
Pinching, // touches have passed the min pinch threshold
Rotating // touches have passed the min rotating threshold
}
;
private _MultiTouchMode _touchMode = _MultiTouchMode.Idle;
private bool _isRotating = false;
private bool _isPinching = false;
private Vector2 _prevVector = Vector2.zero;
public float _minRotationThreshold = 10;
public float _minPinchThreshold = 10;
public override void Process ()
{
if (Input.touchCount == 1) {
bool pressed, released;
PointerEventData touchData = GetTouchPointerEventData (Input.GetTouch (0), out pressed, out released);
eventSystem.RaycastAll (touchData, m_RaycastResultCache);
RaycastResult firstHit = FindFirstRaycast (m_RaycastResultCache);
if (Input.GetTouch (0).phase == TouchPhase.Began) {
ExecuteEvents.Execute (firstHit.go, touchData, ExecuteEvents.beginDragHandler);
}
if (Input.GetTouch (0).phase == TouchPhase.Moved) {
ExecuteEvents.Execute (firstHit.go, touchData, ExecuteEvents.dragHandler);
}
if (Input.GetTouch (0).phase == TouchPhase.Ended) {
ExecuteEvents.Execute (firstHit.go, touchData, ExecuteEvents.endDragHandler);
}
} else if (Input.touchCount == 2) {
bool pressed0, released0;
bool pressed1, released1;
PointerEventData touchData0 = GetTouchPointerEventData (Input.GetTouch (0), out pressed0, out released0);
PointerEventData touchData1 = GetTouchPointerEventData (Input.GetTouch (1), out pressed0, out released1);
eventSystem.RaycastAll (touchData0, m_RaycastResultCache);
RaycastResult firstHit0 = FindFirstRaycast (m_RaycastResultCache);
eventSystem.RaycastAll (touchData1, m_RaycastResultCache);
RaycastResult firstHit1 = FindFirstRaycast (m_RaycastResultCache);
if (Input.GetTouch (0).phase == TouchPhase.Moved || Input.GetTouch (1).phase == TouchPhase.Moved) {
if (firstHit0.go != null && firstHit1.go != null) {
if (firstHit0.go.Equals (firstHit1.go)) {
bool executeHandler = false;
// 'var' works just as well.
BaseEventData motionData = DetectMultiTouchMotion (out executeHandler);
if (executeHandler) {
if (_touchMode == _MultiTouchMode.Pinching) {
_pinchData = motionData as PinchEventData;
_pinchData.data.Add (touchData0);
_pinchData.data.Add (touchData1);
ExecuteEvents.Execute (firstHit0.go, _pinchData, MultiTouchModuleEvents.pinchHandler);
} else if (_touchMode == _MultiTouchMode.Rotating) {
_rotateData = motionData as RotateEventData;
_rotateData.data.Add (touchData0);
_rotateData.data.Add (touchData1);
ExecuteEvents.Execute (firstHit0.go, _rotateData, MultiTouchModuleEvents.rotateHandler);
}
}
}
}
}
if (Input.GetTouch (0).phase == TouchPhase.Ended || Input.GetTouch (1).phase == TouchPhase.Ended ||
Input.GetTouch (0).phase == TouchPhase.Canceled || Input.GetTouch (1).phase == TouchPhase.Canceled) {
_touchMode = _MultiTouchMode.Idle;
_prevVector = Vector2.zero;
}
}
}
BaseEventData DetectMultiTouchMotion (out bool executeHandler)
{
executeHandler = false;
if (_touchMode == _MultiTouchMode.Idle) {
_prevVector = Input.GetTouch (1).position - Input.GetTouch (0).position;
_touchMode = _MultiTouchMode.Began;
return null;
} else if (_touchMode == _MultiTouchMode.Began) {
Vector2 currentVector = Input.GetTouch (1).position - Input.GetTouch (0).position;
//check for rotation threshold
float angleOffset = Vector2.Angle (_prevVector, currentVector);
if (angleOffset > _minRotationThreshold) {
_touchMode = _MultiTouchMode.Rotating;
_prevVector = currentVector;
}
// check for pinch threshold
if (Mathf.Abs (currentVector.magnitude - _prevVector.magnitude) > _minPinchThreshold) {
_touchMode = _MultiTouchMode.Pinching;
_prevVector = currentVector;
}
return null;
} else if (_touchMode == _MultiTouchMode.Rotating) {
Vector2 currentVector = Input.GetTouch (1).position - Input.GetTouch (0).position;
float angleOffset = Vector2.Angle (_prevVector, currentVector);
// to get the direction of rotation
Vector3 dirVec = Vector3.Cross (_prevVector, currentVector);
_prevVector = currentVector;
executeHandler = true;
return new RotateEventData (eventSystem, dirVec.z < 0 ? -angleOffset : angleOffset);
} else if (_touchMode == _MultiTouchMode.Pinching) {
Vector2 currentVector = Input.GetTouch (1).position - Input.GetTouch (0).position;
float pinchDelta = currentVector.magnitude - _prevVector.magnitude;
_prevVector = currentVector;
executeHandler = true;
return new PinchEventData (eventSystem, pinchDelta);
}
return null;
}
public override string ToString ()
{
return string.Format ("[MultiTouchInputModule]");
}
}
}
Thank you,
Nihal