Skip to content

Instantly share code, notes, and snippets.

@jinwoo-lee-github
Forked from asus4/TouchToMouseConverter.cs
Last active July 27, 2017 07:30
Show Gist options
  • Save jinwoo-lee-github/7117513 to your computer and use it in GitHub Desktop.
Save jinwoo-lee-github/7117513 to your computer and use it in GitHub Desktop.
ATTouch for Unity ( mobile & editor)
/**
Converts Mobile Touch to the default Mouse Click
## invoked these method in Mobile too
OnMouseDown
OnMouseDrag
OnMouseUp
## only called in touch screen
OnPinchStart
OnPinch(rate:float);
OnPinchEnd
@author koki ibukuro
@author whdvl
*/
using System;
using System.Collections;
using System.Reflection;
using UnityEngine;
[AddComponentMenu ("AT/ATTouch")]
public class ATTouch : MonoBehaviour {
/**
State for convert mouse event
*/
private enum TouchToMouseState {
Down,
Drag,
Up,
Pinching,
PinchEnd
}
public bool isOn = true;
private TouchToMouseState touchState = TouchToMouseState.Up;
private RaycastHit hit;
private Transform beforeTransform;
//private float DRAGGING_DISTANSE = 100f;
static Camera cam;
static Transform camTransform;
static private int kRaycastLayers = 0; // 1 << 8 Physics
/// <summary>
/// returns mouse or first touched point
/// </summary>
/// <returns></returns>
static public Vector3 GetMousePosition() {
if(Input.touchCount > 0) {
return Input.GetTouch(0).position;
}
return Input.mousePosition;
}
/// <summary>
/// returns mouse or touched point in World
/// </summary>
static public Vector3 GetWorldMousePosition() {
Vector3 mousePosition = GetMousePosition();
Vector3 cameraPosition = camTransform.position;
return cam.ScreenToWorldPoint(new Vector3(mousePosition.x, mousePosition.y, cameraPosition.z));
}
private static object _lock = new object();
private static ATTouch _instance;
public static ATTouch Instance
{
get
{
lock(_lock)
{
if (_instance == null)
{
_instance = (ATTouch) FindObjectOfType(typeof(ATTouch));
if (_instance == null)
{
GameObject singleton = new GameObject();
_instance = singleton.AddComponent<ATTouch>();
singleton.name = typeof(ATTouch).ToString();
ATLog.Log("[Singleton] An instance of " + typeof(ATTouch) + " is needed in the scene, so '" + singleton + "' was created with DontDestroyOnLoad.");
}
DontDestroyOnLoad(_instance);
}
return _instance;
}
}
}
/// <summary>
/// set Using camera
/// </summary>
static public void SetCamera(Camera c) {
cam = c;
camTransform = c.transform;
kRaycastLayers = cam.cullingMask;
}
void Start () {
if(!cam) {
SetCamera(Camera.main);
}
}
void Update () {
if (!isOn) {
return;
}
if ( OneClick () ) {
if(touchState == TouchToMouseState.Pinching ) {
touchState = TouchToMouseState.PinchEnd;
toPinchEnd();
}
else if(touchState == TouchToMouseState.PinchEnd) {
// nothing to do
}
else {
singleTouch();
}
}
else if( multiClick () ) {
multiTouch();
}
else {
noTouch();
}
callGC();
}
bool OneClick() {
int count = Input.touchCount;
return count == 1 || Input.GetMouseButton(0);
}
bool multiClick () {
int count = Input.touchCount;
return count >= 2;
}
private void singleTouch() {
if(Input.touchCount > 0) {
Touch touch = Input.GetTouch(0);
Ray ray = cam.ScreenPointToRay ( GetMousePosition());
// if it has hitting object....
//if ( !UIManager.instance.DidAnyPointerHitUI() && Physics.Raycast( ray, hit, Mathf.Infinity, kRaycastLayers) ) {
if ( Physics.Raycast( ray, out hit, Mathf.Infinity, kRaycastLayers) ) {
// start touch
if(touch.phase == TouchPhase.Began) {
toDown();
}
// touch move
else if(touch.phase == TouchPhase.Moved) {
if(beforeTransform == hit.transform) {
toDrag();
}
else {
toOldUp();
toDown();
}
}
// end touch
else if(touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled) {
toUp();
}
if(touchState == TouchToMouseState.Drag && hit.transform != beforeTransform){
toOldUp();
}
}
else {
// if dragging,,, send message to the old touched object
if(touchState == TouchToMouseState.Drag) {
if(touch.phase == TouchPhase.Moved) {
toOldDrag();
}
else if(touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled) {
toOldUp();
}
}
}
} else {
//for editor
#if UNITY_EDITOR
Ray ray = cam.ScreenPointToRay ( GetMousePosition() );
if ( Physics.Raycast( ray, out hit, Mathf.Infinity, kRaycastLayers) ) {
if(Input.GetMouseButtonUp(0)) {
toUp();
touchState = TouchToMouseState.Up;
} else if (Input.GetMouseButton(0)) {
if(touchState == TouchToMouseState.Up) {
toDown();
touchState = TouchToMouseState.Down;
} else if(touchState == TouchToMouseState.Down) {
toDrag();
touchState = TouchToMouseState.Drag;
} else {
toDrag();
}
}
}
#endif
}
}
private float _touchesDistance = 0;
private void multiTouch() {
Touch a = Input.GetTouch(0);
Touch b = Input.GetTouch(1);
if((a.phase == TouchPhase.Stationary || a.phase == TouchPhase.Moved)
&&(b.phase == TouchPhase.Stationary || b.phase == TouchPhase.Moved))
{
Ray ray = cam.ScreenPointToRay ( a.position);
// There are hitting objects..
if ( Physics.Raycast( ray,out hit, Mathf.Infinity, kRaycastLayers) ) {
float d = Vector2.Distance(a.position, b.position);
if(touchState != TouchToMouseState.Pinching) {
_touchesDistance = d;
toPinchStart();
touchState = TouchToMouseState.Pinching;
}
else {
toPinch(d/_touchesDistance);
}
}
else {
}
}
}
private void noTouch() {
if(touchState == TouchToMouseState.Pinching) {
touchState = TouchToMouseState.PinchEnd;
}
else if(touchState == TouchToMouseState.PinchEnd) {
touchState = TouchToMouseState.Up;
}
else if(beforeTransform) {
toOldUp();
}
}
private void callGC() {
if(Time.frameCount % 30 == 0) {
System.GC.Collect();
}
}
private void toDown() {
hit.transform.SendMessage("OnMouseDown",null, SendMessageOptions.DontRequireReceiver);
touchState = TouchToMouseState.Down;
beforeTransform = hit.transform;
}
private void toDrag() {
hit.transform.SendMessage("OnMouseDrag",GetWorldMousePosition(), SendMessageOptions.DontRequireReceiver);
touchState = TouchToMouseState.Drag;
beforeTransform = hit.transform;
}
private void toUp() {
hit.transform.SendMessage("OnMouseUp",null, SendMessageOptions.DontRequireReceiver);
touchState = TouchToMouseState.Up;
beforeTransform = null;
}
private void toOldDrag () {
beforeTransform.SendMessage("OnMouseDrag",null, SendMessageOptions.DontRequireReceiver);
}
private void toOldUp () {
if(beforeTransform)beforeTransform.SendMessage("OnMouseUp",null, SendMessageOptions.DontRequireReceiver);
beforeTransform = null;
}
private void toPinchStart() {
hit.transform.SendMessage("OnPinchStart",null, SendMessageOptions.DontRequireReceiver);
}
private void toPinch(float rate) {
hit.transform.SendMessage("OnPinch",rate, SendMessageOptions.DontRequireReceiver);
}
private void toPinchEnd() {
hit.transform.SendMessage("OnPinchEnd",null, SendMessageOptions.DontRequireReceiver);
}
}
@jinwoo-lee-github
Copy link
Author

Change

  • singleton
  • for editor touch. (mouse)
    • currently not support multiTouch();

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