-
-
Save nicloay/d13f5c8fa8e1b81eddac92057643308f to your computer and use it in GitHub Desktop.
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 System.Collections.Generic; | |
using System.Linq; | |
using System.Reflection; | |
using DigitalRubyShared; | |
using UnityEngine; | |
using UnityEngine.EventSystems; | |
using TouchPhase = DigitalRubyShared.TouchPhase; | |
public class VectorPair | |
{ | |
public Vector2 Current; | |
public Vector2 Previous; | |
public Vector2 Delta | |
{ | |
get { return Current - Previous; } | |
} | |
} | |
public class StickerGesturesCtrl : MonoBehaviour | |
{ | |
public Action<GameObject, VectorPair> OnStickerPan; | |
public Action<GameObject, VectorPair, VectorPair> OnStickerPinch;//<figer1, finger2> (each has current and rprevious) | |
public Action OnAllGesturesDone; | |
private int _stickerLayer; | |
private PanGestureRecognizer _panGesture; | |
private Camera _camera; | |
void Awake () | |
{ | |
_camera = Camera.main; | |
_stickerLayer = 1 << this.gameObject.layer; | |
_panGesture = new PanGestureRecognizer { MinimumNumberOfTouchesToTrack = 1, MaximumNumberOfTouchesToTrack = 5, ThresholdUnits = 0.0f }; | |
} | |
private void OnEnable() | |
{ | |
FingersScript.Instance.AddGesture(_panGesture); | |
_panGesture.StateUpdated += OnPanStateUpdated; | |
} | |
private void OnDisable() | |
{ | |
_panGesture.StateUpdated -= OnPanStateUpdated; | |
FingersScript.Instance.RemoveGesture(_panGesture); | |
} | |
private void OnPanStateUpdated(GestureRecognizer gesture) | |
{ | |
switch (gesture.State) | |
{ | |
case GestureRecognizerState.Began: | |
case GestureRecognizerState.Executing: | |
case GestureRecognizerState.Ended: | |
UpdateDragStates(); | |
break; | |
} | |
} | |
Dictionary<int, StickerInfo> _stickerInfoByTouchId= new Dictionary<int, StickerInfo>(); | |
Dictionary<GameObject, StickerInfo> _stickerInfoByGO = new Dictionary<GameObject, StickerInfo>(); | |
private void UpdateDragStates() | |
{ | |
// collect objects by finger id | |
foreach (GestureTouch touch in _panGesture.CurrentTrackedTouches) | |
{ | |
if (_stickerInfoByTouchId.ContainsKey(touch.Id)) | |
{ | |
// already have one - do nothing? | |
} | |
else | |
{ | |
// find gameobject | |
GameObject stickerGO = GetGOForTouch(touch); | |
if (stickerGO != null) | |
{ | |
StickerInfo stickerInfo; | |
if (_stickerInfoByGO.ContainsKey(stickerGO)) | |
{ | |
stickerInfo = _stickerInfoByGO[stickerGO]; | |
if (!stickerInfo.TouchID.Contains(touch.Id)) | |
{ | |
stickerInfo.TouchID.Add(touch.Id); | |
} | |
} | |
else | |
{ | |
stickerInfo = new StickerInfo() | |
{ | |
Sticker = stickerGO, | |
TouchID = new List<int>() {touch.Id} | |
}; | |
_stickerInfoByGO.Add(stickerGO, stickerInfo); | |
} | |
_stickerInfoByTouchId.Add(touch.Id, stickerInfo); | |
} | |
else | |
{ | |
// didn't WheelHit any sticker here | |
} | |
} | |
} | |
//iterate over all fingers and report movement | |
foreach (StickerInfo stickerInfo in _stickerInfoByGO.Values) | |
{ | |
GestureTouch gt = GetTouchById(stickerInfo.TouchID[0]); | |
if (stickerInfo.TouchID.Count == 1) | |
{ | |
if (gt.TouchPhase == TouchPhase.Moved) | |
{ | |
OnStickerPan.Invoke(stickerInfo.Sticker, | |
new VectorPair() | |
{ | |
Current = _camera.ScreenToWorldPoint(gt.ScreenPosition), | |
Previous = _camera.ScreenToWorldPoint(gt.PreviousPosition) | |
}); | |
} | |
} | |
else | |
{ | |
GestureTouch gt2 = GetTouchById(stickerInfo.TouchID[1]); | |
if (gt.TouchPhase == TouchPhase.Moved || gt2.TouchPhase == TouchPhase.Moved) | |
{ | |
OnStickerPinch.Invoke(stickerInfo.Sticker, | |
new VectorPair() | |
{ | |
Current = _camera.ScreenToWorldPoint(gt.ScreenPosition), | |
Previous = _camera.ScreenToWorldPoint(gt.PreviousPosition) | |
}, | |
new VectorPair() | |
{ | |
Current = _camera.ScreenToWorldPoint(gt2.ScreenPosition), | |
Previous = _camera.ScreenToWorldPoint(gt2.PreviousPosition) | |
}); | |
} | |
} | |
} | |
if (_panGesture.State == GestureRecognizerState.Ended) | |
{ | |
_stickerInfoByGO.Clear(); | |
_stickerInfoByTouchId.Clear(); | |
OnAllGesturesDone.Invoke(); | |
} | |
} | |
GestureTouch GetTouchById(int id) | |
{ | |
return _panGesture.CurrentTrackedTouches.First(touch => touch.Id == id); | |
} | |
GameObject GetGOForTouch(GestureTouch touch) | |
{ | |
int nativeTouchId = touch.Id; | |
// if (EventSystem.current.IsPointerOverGameObject(nativeTouchId)) | |
// { | |
// return null; | |
// } | |
var inputModule = EventSystem.current.currentInputModule; | |
MethodInfo methodInfo = inputModule.GetType().GetMethod("GetLastPointerEventData", BindingFlags.Instance | BindingFlags.NonPublic); | |
PointerEventData pointerEventData = | |
(PointerEventData) methodInfo.Invoke(inputModule, new object[] {nativeTouchId}); | |
if (pointerEventData != null && pointerEventData.pointerDrag != null && pointerEventData.pointerDrag.layer != this.gameObject.layer) | |
{ | |
return null; | |
} | |
var ray = _camera.ScreenPointToRay(touch.ScreenPosition); | |
var intersection = Physics2D.GetRayIntersection(ray, 1000, _stickerLayer); | |
return intersection != null && intersection.collider != null ? intersection.transform.gameObject : null; | |
} | |
private class StickerInfo | |
{ | |
public GameObject Sticker; | |
public List<int> TouchID; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment