Skip to content

Instantly share code, notes, and snippets.

@joonjoonjoon
Created March 15, 2017 17:34
Show Gist options
  • Select an option

  • Save joonjoonjoon/9d6a60d6ed76d69a1c3f36e0836ca94a to your computer and use it in GitHub Desktop.

Select an option

Save joonjoonjoon/9d6a60d6ed76d69a1c3f36e0836ca94a to your computer and use it in GitHub Desktop.
InputHelper + GlitchTouch
using UnityEngine;
using System.Collections.Generic;
public class GlitchTouch
{
public const int MAXFINGERS = 11;
private static Vector2[] positionHistory; //indexed by finger
public float deltaTime;
public int tapCount;
public TouchPhase phase;
public Vector2 deltaPosition;
private Vector2 _deltaPositionCalculated;
public int fingerId;
public Vector2 position;
public Vector2 rawPosition;
public Vector2 deltaPositionCalculated
{
get
{
if (fingerId <= MAXFINGERS)
return _deltaPositionCalculated;
else
return deltaPosition;
}
}
public GlitchTouch()
{
}
public GlitchTouch(Touch touch)
{
this.deltaPosition = touch.deltaPosition;
this.deltaTime = touch.deltaTime;
this.tapCount = touch.tapCount;
this.phase = touch.phase;
this.fingerId = touch.fingerId;
this.position = touch.position;
this.rawPosition = touch.rawPosition;
if (positionHistory == null) positionHistory = new Vector2[MAXFINGERS];
if (touch.phase == TouchPhase.Moved || touch.phase == TouchPhase.Stationary)
{
this._deltaPositionCalculated = this.position - positionHistory[touch.fingerId];
positionHistory[touch.fingerId] = touch.position;
}
else
{
positionHistory[touch.fingerId] = touch.position; ;
}
}
public GlitchTouch(float deltaTime, int tapCount, TouchPhase phase, Vector2 deltaPosition, int fingerId, Vector2 position, Vector2 rawPosition)
{
this.deltaPosition = deltaPosition;
this.deltaTime = deltaTime;
this.tapCount = tapCount;
this.phase = phase;
this.fingerId = fingerId;
this.position = position;
this.rawPosition = rawPosition;
if (positionHistory == null) positionHistory = new Vector2[MAXFINGERS];
if (phase == TouchPhase.Moved || phase == TouchPhase.Stationary)
{
this._deltaPositionCalculated = this.position - positionHistory[fingerId];
positionHistory[fingerId] = position;
}
else
{
positionHistory[fingerId] = position; ;
}
}
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
// Mobile touches show up as Input.GetMouseButtonDown(0) but not vice versa. A mouse does not show up in Input.GetTouches.
// use InputHelper.GetTouches if you've implemented touch, and want the mouse to act like a touch...
[ScriptOrder(-1000)] //TODO: figure out better number...
[MonoSingleton(false, true)]
public class InputHelper : MonoSingleton<InputHelper>
{
private static GlitchTouch lastFakeTouch;
private static float lastFakeTouchTime;
private static List<GlitchTouch> touches;
private bool queueRelease;
void Update()
{
touches = new List<GlitchTouch>();
for (int i = 0; i < Input.touchCount; i++)
{
touches.Add(new GlitchTouch(Input.GetTouch(i)));
}
#if (UNITY_EDITOR || UNITY_STANDALONE || UNITY_WEBPLAYER || UNITY_WEBGL)
if (queueRelease)
{
//Mouse tap received last frame, end touch this frame to simulate a tap.
EndFakeTouch();
}
else if (Input.GetMouseButtonDown(0) && IsMouseWithinScreenBounds())
{
//Begin touch because mouse is within bounds
BeginFakeTouch();
//NOTE: (Down and Up in the same frame) == Mouse tap
//Did we only recieve a tap? Schedule a release next frame!
if (Input.GetMouseButtonUp(0))
{
queueRelease = true;
}
}
else if (Input.GetMouseButtonUp(0) || !IsMouseWithinScreenBounds())
{
//If the touch had previously been registered, and mouse up or mouse leaves screen bounds, end the fake touch.
if (lastFakeTouch != null && lastFakeTouch.phase != TouchPhase.Ended)
{
EndFakeTouch();
}
else
{
lastFakeTouch = null;
}
}
else if (Input.GetMouseButton(0) && IsMouseWithinScreenBounds())
{
//NOTE: TouchPhase.Cancelled is never used for FakeTouches, so can be ignored.
//If the touch previously began, moved or stayed, update the fake touch.
if (lastFakeTouch != null && lastFakeTouch.phase != TouchPhase.Ended)
{
if ((new Vector2(Input.mousePosition.x, Input.mousePosition.y) - lastFakeTouch.position).magnitude < 0.1f)
{
StayFakeTouch();
}
else
{
MoveFakeTouch();
}
}
else
{
//NOTE: For some reason GetMouseButton does not return true if OnMouseDown happens outside of screen.
//Mouse was down outside screen bounds, meaning we should simulate a new touch, when it comes back!
BeginFakeTouch();
}
}
else
{
lastFakeTouch = null;
}
if (lastFakeTouch != null)
touches.Add(lastFakeTouch);
#endif
}
#region FakeTouch helpers
private void BeginFakeTouch()
{
if (lastFakeTouch == null)
lastFakeTouch = new GlitchTouch();
lastFakeTouch.phase = TouchPhase.Began;
lastFakeTouch.deltaPosition = Vector2.zero;
lastFakeTouch.deltaTime = Time.unscaledDeltaTime;
lastFakeTouch.position = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
lastFakeTouch.fingerId = GlitchTouch.MAXFINGERS +1 ;
}
private void MoveFakeTouch()
{
if (lastFakeTouch == null)
lastFakeTouch = new GlitchTouch();
lastFakeTouch.phase = TouchPhase.Moved;
Vector2 newPosition = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
lastFakeTouch.deltaPosition = newPosition - lastFakeTouch.position;
lastFakeTouch.deltaTime = Time.unscaledDeltaTime;
lastFakeTouch.position = newPosition;
lastFakeTouch.fingerId = GlitchTouch.MAXFINGERS + 1;
}
private void StayFakeTouch()
{
if (lastFakeTouch == null)
lastFakeTouch = new GlitchTouch();
lastFakeTouch.phase = TouchPhase.Stationary;
Vector2 newPosition = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
lastFakeTouch.deltaPosition = Vector2.zero;
lastFakeTouch.deltaTime = Time.unscaledDeltaTime;
lastFakeTouch.position = newPosition;
lastFakeTouch.fingerId = GlitchTouch.MAXFINGERS + 1;
}
private void EndFakeTouch()
{
if (lastFakeTouch == null)
lastFakeTouch = new GlitchTouch();
lastFakeTouch.phase = TouchPhase.Ended;
//lastFakeTouch.deltaPosition = lastFakeTouch.deltaPosition;
//lastFakeTouch.deltaTime = lastFakeTouch.deltaTime;
//lastFakeTouch.position = lastFakeTouch.position;
lastFakeTouch.fingerId = GlitchTouch.MAXFINGERS + 1;
queueRelease = false;
}
private bool IsMouseWithinScreenBounds()
{
if (0 < Input.mousePosition.x && Input.mousePosition.x < Screen.width &&
0 < Input.mousePosition.y && Input.mousePosition.y < Screen.height)
{
return true;
}
return false;
}
#endregion
public static List<GlitchTouch> GetTouches()
{
if (instance == null)
instance.Update(); // it's possible that only this static method is touched, and thus the singleton is never initialized.
if (touches == null) touches = new List<GlitchTouch>(); // for some reason it returns null on the first run through...
return touches;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment