Skip to content

Instantly share code, notes, and snippets.

@treefortress
Last active August 29, 2015 14:07
Show Gist options
  • Save treefortress/67551084ea14bc99d176 to your computer and use it in GitHub Desktop.
Save treefortress/67551084ea14bc99d176 to your computer and use it in GitHub Desktop.
Extension for InControl Unity Controller Plugin - Allows creation of Simple Touch Buttons from any GameObject.
using UnityEngine;
using System.Collections;
using System;
using InControl;
/**
* Attach to a GameObject with a Collider2D component to create a simple button
* which dispatches TouchStart and TouchEnd events.
* Optionally, specify an InControl Action to activate.
**/
public class SimpleTouchControl : MonoBehaviour {
//Activate an InControl button (Optional)
public TouchControl.ButtonTarget buttonTarget = TouchControl.ButtonTarget.None;
//Button will stay active when the user drags their finger outside the button bounds.
public bool enableReleaseOutside = false;
//User can activate button by draging their finger over it
public bool enableDragOver = false;
//Notify Listeners when we've been Touched/Clicked
public Action TouchStarted;
public Action TouchEnded;
protected bool wasJustPressed;
protected bool isPressed;
protected InputControl control;
protected InControl.Touch activeTouch;
protected void Start() {
//Auto-assign this gameObject to the UI layer, so SimpleTouchManager can hit it with a raycast
gameObject.layer = LayerMask.NameToLayer("UI");
InputManager.OnUpdate += OnInputManagerUpdate;
if (buttonTarget != TouchControl.ButtonTarget.None) {
control = InputManager.ActiveDevice.GetControl((InputControlType)buttonTarget);
}
}
protected void Update() {
if (activeTouch != null) {
//End touch once the user releases their finger.
if (activeTouch.phase == TouchPhase.Ended) {
TouchUp();
}
//If releaseOutside is not enabled, TouchUp should trigger as the touch leaves our collider
else if (enableReleaseOutside == false && activeTouch.phase == TouchPhase.Moved) {
var touchPos = TouchManager.ScreenToWorldPoint(activeTouch.lastPosition);
if (collider2D.bounds.Contains(touchPos) == false) {
TouchUp();
}
}
}
}
protected void OnInputManagerUpdate(ulong arg1, float arg2) {
if (control != null && control.IsNotNull) {
control.UpdateWithState(isPressed, control.UpdateTick);
}
}
public void TouchDown(InControl.Touch touch) {
if (IsTouched) { return; }
activeTouch = touch;
IsTouched = true;
WasJustTouched = true;
StartCoroutine(_EndWasTouched());
if (TouchStarted != null) { TouchStarted(); }
}
protected IEnumerator _EndWasTouched() {
yield return new WaitForEndOfFrame();
WasJustTouched = false;
}
public void TouchUp(InControl.Touch touch = null) {
if (!IsTouched) { return; }
if (touch != null && touch != activeTouch) { return; }
IsTouched = false;
WasJustTouched = false;
activeTouch = null;
if (TouchEnded != null) { TouchEnded(); }
}
public InControl.Touch ActiveTouch { get { return activeTouch; } }
public bool WasJustTouched {
get { return wasJustPressed; }
private set { wasJustPressed = value; }
}
public bool IsTouched {
get { return isPressed; }
private set { isPressed = value; }
}
}
using UnityEngine;
using System.Collections;
using InControl;
/** Attach this to some persistent object in your scene **/
public class SimpleTouchManager : MonoBehaviour
{
void Update() {
//All Buttons should exist on the UI layer to avoid collisions with other GameObjects.
int UILayerMask = 1 << LayerMask.NameToLayer("UI");
foreach (var touch in TouchManager.Touches) {
Vector3 pos = TouchManager.ScreenToWorldPoint(touch.lastPosition);
pos.z = Camera.main.transform.position.z;
RaycastHit2D hit = Physics2D.Raycast(pos, Vector3.forward * -pos.z, 0, UILayerMask);
if (hit.collider != null) {
var touchControl = hit.collider.GetComponent<SimpleTouchControl>();
if (touchControl) {
//Normal Touch Started
if (touch.phase == TouchPhase.Began) {
touchControl.TouchDown(touch);
}
//DragOver Touch Started
else if (touchControl.enableDragOver && touch.phase == TouchPhase.Moved && touchControl.ActiveTouch == null) {
touchControl.TouchDown(touch);
}
}
//Support generic OnMouseDown and OnMouseUp events.
else {
if (touch.phase == TouchPhase.Began) {
hit.collider.SendMessage("OnMouseDown", SendMessageOptions.DontRequireReceiver);
}
else if (touch.phase == TouchPhase.Ended) {
hit.collider.SendMessage("OnMouseUp", SendMessageOptions.DontRequireReceiver);
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment