Skip to content

Instantly share code, notes, and snippets.

@nir1082
Last active November 6, 2018 07:59
Show Gist options
  • Save nir1082/9ce1ff6e3b521168a36e55bd26385fab to your computer and use it in GitHub Desktop.
Save nir1082/9ce1ff6e3b521168a36e55bd26385fab to your computer and use it in GitHub Desktop.
[Unity] オレオレTouchManager
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class TouchManager : MonoBehaviour
{
static TouchManager s_Instance;
static public TouchManager instance {
get {
if (s_Instance == null) {
s_Instance = new GameObject ("TouchManager").AddComponent<TouchManager> ();
}
return s_Instance;
}
}
public int maxTouchCount = 5;
public float limitOfTapTime = 2.0f;
public float limitOfFlickTime = 2.0f;
public float flickSensitivity = 1000.0f;
public bool useMouse = true;
public int mouseButtonCount = 2;
TouchAndMouse[] m_TouchSensors;
bool m_IsActive = true;
public bool IsActive ()
{
return m_IsActive;
}
public void SetActive (bool isActive)
{
m_IsActive = isActive;
}
public int TouchSensorCount ()
{
return m_TouchSensors.Length;
}
public int TouchCount ()
{
int touchCount = 0;
for (int i = 0; i < m_TouchSensors.Length; i++) {
if (m_TouchSensors [i].IsActive) {
touchCount++;
}
}
return touchCount;
}
public bool IsTapped ()
{
for (int i = 0; i < m_TouchSensors.Length; i++) {
if (IsTapped (i)) {
return true;
}
}
return false;
}
public float TouchTime ()
{
float touchTime = -1.0f;
for (int i = 0; i < m_TouchSensors.Length; i++) {
touchTime = TouchTime (i);
if (touchTime != -1.0f) {
break;
}
}
return touchTime;
}
public float TouchTime (int fingerID)
{
if (m_TouchSensors [fingerID].IsActive) {
return (Time.realtimeSinceStartup - m_TouchSensors [fingerID].TouchBeganTime);
}
return -1.0f;
}
public bool IsTapped (out int fingerID)
{
fingerID = -1;
for (int i = 0; i < m_TouchSensors.Length; i++) {
if (IsTapped (i)) {
fingerID = i;
return true;
}
}
return false;
}
public bool IsTapped (int fingerID)
{
if (m_TouchSensors [fingerID].IsActive
&& m_TouchSensors [fingerID].TouchDeltaTime > 0.0f
&& m_TouchSensors [fingerID].TouchDeltaTime < limitOfTapTime
&& m_TouchSensors [fingerID].Movement.sqrMagnitude < flickSensitivity) {
return true;
}
return false;
}
public bool IsTapped (Transform target)
{
List<Camera> cams = new List<Camera> ();
foreach (Camera cam in Camera.allCameras) {
cams.Add (cam);
}
cams.Sort ((Camera a, Camera b) => (int)b.depth - (int)a.depth);
for (int i = 0; i < cams.Count; i++) {
if (IsTapped (target, cams [i])) {
return true;
}
}
return false;
}
public bool IsTapped (Transform target, Camera cam)
{
return IsTapped (target, cam, ~0);
}
public bool IsTapped (Transform target, Camera cam, int layerMask)
{
if (cam.orthographic) {
for (int i = 0; i < m_TouchSensors.Length; i++) {
Vector3 touchViewPoint;
touchViewPoint = cam.ScreenToViewportPoint (m_TouchSensors [i].Position);
if (touchViewPoint.x < 0.0f
|| touchViewPoint.x > 1.0f
|| touchViewPoint.y < 0.0f
|| touchViewPoint.y > 1.0f) {
continue;
}
if (IsTapped (i)) {
Ray ray;
RaycastHit hit;
ray = cam.ScreenPointToRay (m_TouchSensors [i].Position);
if (Physics.Raycast (ray, out hit, 1000.0f, layerMask)) {
if (hit.transform == target) {
return true;
}
}
}
}
}
return false;
}
public bool IsFlicked ()
{
for (int i = 0; i < m_TouchSensors.Length; i++) {
if (IsFlicked (i)) {
return true;
}
}
return false;
}
public bool IsFlicked (int fingerID)
{
if (m_TouchSensors [fingerID].IsActive
&& m_TouchSensors [fingerID].Movement.sqrMagnitude > flickSensitivity
&& m_TouchSensors [fingerID].TouchDeltaTime > 0.0f
&& m_TouchSensors [fingerID].TouchDeltaTime < limitOfFlickTime) {
return true;
}
return false;
}
public bool IsTouched ()
{
for (int i = 0; i < m_TouchSensors.Length; i++) {
if (IsTouched (i)) {
return true;
}
}
return false;
}
public bool IsTouched (out int fingerID)
{
for (int i = 0; i < m_TouchSensors.Length; i++) {
if (IsTouched (i)) {
fingerID = i;
return true;
}
}
fingerID = -1;
return false;
}
public bool IsTouched (int fingerID)
{
TouchPhase phase = TouchPhase.Ended;
return IsTouched (fingerID, out phase);
}
public bool IsTouched (int fingerID, out TouchPhase phase)
{
if (fingerID >= 0
&& fingerID < m_TouchSensors.Length) {
if (m_TouchSensors [fingerID].IsActive) {
phase = m_TouchSensors [fingerID].Phase;
return true;
}
}
phase = TouchPhase.Ended;
return false;
}
public bool IsTouched (Transform target)
{
List<Camera> cams = new List<Camera> ();
foreach (Camera cam in Camera.allCameras) {
cams.Add (cam);
}
cams.Sort ((Camera a, Camera b) => (int)b.depth - (int)a.depth);
for (int i = 0; i < cams.Count; i++) {
if (IsTouched (target, cams [i])) {
return true;
}
}
return false;
}
public bool IsTouched (Transform target, Camera cam)
{
return IsTouched (target, cam, ~0);
}
public bool IsTouched (Transform target, Camera cam, int layerMask)
{
for (int i = 0; i < m_TouchSensors.Length; i++) {
if (IsTouched (target, cam, i, layerMask)) {
return true;
}
}
return false;
}
public bool IsTouched (Transform target, Camera cam, int fingerID, int layerMask)
{
if (!m_TouchSensors [fingerID].IsActive) {
return false;
}
Ray ray;
ray = cam.ScreenPointToRay (m_TouchSensors [fingerID].Position);
RaycastHit[] hits = Physics.RaycastAll (ray, 1000.0f, layerMask);
foreach (RaycastHit hit in hits) {
if (hit.transform == target) {
return true;
}
}
return false;
}
public bool EqualPhase (TouchPhase phase)
{
for (int i = 0; i < m_TouchSensors.Length; i++) {
if (EqualPhase (phase, i)) {
return true;
}
}
return false;
}
public bool EqualPhase (TouchPhase phase, int fingerID)
{
if (fingerID >= 0
&& m_TouchSensors [fingerID].IsActive) {
if (m_TouchSensors [fingerID].Phase == phase) {
return true;
}
}
return false;
}
public bool EqualPhase (TouchPhase phase, out int fingerID)
{
for (int i = 0; i < m_TouchSensors.Length; i++) {
if (m_TouchSensors [i].IsActive) {
if (m_TouchSensors [i].Phase == phase) {
fingerID = i;
return true;
}
}
}
fingerID = -1;
return false;
}
public Vector2 DeltaMovement ()
{
Vector2 deltaMovement = Vector2.zero;
for (int i = 0; i < m_TouchSensors.Length; i++) {
deltaMovement = DeltaMovement (i);
if (deltaMovement != Vector2.zero) {
break;
}
}
return deltaMovement;
}
public Vector2 DeltaMovement (int fingerID)
{
if (m_TouchSensors [fingerID].IsActive) {
return m_TouchSensors [fingerID].DeltaMovement;
}
return Vector2.zero;
}
public Vector2 Movement ()
{
Vector2 movement = Vector2.zero;
for (int i = 0; i < m_TouchSensors.Length; i++) {
movement = Movement (i);
if (movement != Vector2.zero) {
break;
}
}
return movement;
}
public Vector2 Movement (int fingerID)
{
if (m_TouchSensors [fingerID].IsActive) {
return m_TouchSensors [fingerID].Movement;
}
return Vector2.zero;
}
public Vector2 Move4Direction ()
{
Vector2 direction = Vector2.zero;
for (int i = 0; i < m_TouchSensors.Length; i++) {
direction = Move4Direction (i);
if (direction != Vector2.zero) {
break;
}
}
return direction;
}
public Vector2 Move4Direction (int fingerID)
{
Vector2 direction = MoveDirection (fingerID);
if (direction == Vector2.zero) {
return direction;
}
if (Mathf.Abs (direction.x) > Mathf.Abs (direction.y)) {
return Vector2.right * Mathf.Sign (direction.x);
} else {
return Vector2.up * Mathf.Sign (direction.y);
}
}
public Vector2 MoveDirection ()
{
Vector2 swipeDirection = Vector2.zero;
for (int i = 0; i < m_TouchSensors.Length; i++) {
swipeDirection = MoveDirection (i);
if (swipeDirection != Vector2.zero) {
break;
}
}
return swipeDirection;
}
public Vector2 MoveDirection (int fingerID)
{
if (m_TouchSensors [fingerID].IsActive) {
return m_TouchSensors [fingerID].MoveDirection;
}
return Vector2.zero;
}
public Vector2 DeltaMove4Direction ()
{
Vector2 direction = Vector2.zero;
for (int i = 0; i < m_TouchSensors.Length; i++) {
direction = DeltaMove4Direction (i);
if (direction != Vector2.zero) {
break;
}
}
return direction;
}
public Vector2 DeltaMove4Direction (int fingerID)
{
Vector2 direction;
direction = DeltaMoveDirection (fingerID);
if (direction == Vector2.zero) {
return direction;
}
if (Mathf.Abs (direction.x) > Mathf.Abs (direction.y)) {
return Vector2.right * Mathf.Sign (direction.x);
} else {
return Vector2.up * Mathf.Sign (direction.y);
}
}
public Vector2 DeltaMoveDirection ()
{
Vector2 deltaMoveDirection = Vector2.zero;
for (int i = 0; i < m_TouchSensors.Length; i++) {
deltaMoveDirection = DeltaMoveDirection (i);
if (deltaMoveDirection != Vector2.zero) {
break;
}
}
return deltaMoveDirection;
}
public Vector2 DeltaMoveDirection (int fingerID)
{
return m_TouchSensors [fingerID].DeltaMovement;
}
public Vector2 TouchPosition ()
{
Vector2 position = Vector2.zero;
for (int i = 0; i < m_TouchSensors.Length; i++) {
if (m_TouchSensors [i].IsActive) {
position = m_TouchSensors [i].Position;
break;
}
}
return position;
}
public Vector2 TouchPosition (int fingerID)
{
return m_TouchSensors [fingerID].Position;
}
public Transform TappedTransform ()
{
Transform tappedTransform;
tappedTransform = null;
for (int i = 0; i < m_TouchSensors.Length; i++) {
tappedTransform = TappedTransform (i);
if (tappedTransform != null) {
break;
}
}
return tappedTransform;
}
public Transform TappedTransform (Camera cam)
{
for (int i = 0; i < m_TouchSensors.Length; i++) {
if (!m_TouchSensors [i].IsActive) {
continue;
}
return TappedTransform (cam, i, ~0);
}
return null;
}
public Transform TappedTransform (int fingerID)
{
return TappedTransform (fingerID, ~0);
}
public Transform TappedTransform (Camera cam, int fingerID)
{
return TappedTransform (cam, fingerID, ~0);
}
public Transform TappedTransform (int fingerID, int layerMask)
{
if (!m_TouchSensors [fingerID].IsActive || !IsTapped (fingerID)) {
return null;
}
Transform tappedTransform;
List<Camera> cams = new List<Camera> ();
foreach (Camera cam in Camera.allCameras) {
cams.Add (cam);
}
cams.Sort ((Camera a, Camera b) => (int)b.depth - (int)a.depth);
tappedTransform = null;
for (int i = 0; i < cams.Count; i++) {
tappedTransform = TappedTransform (cams [i], fingerID, layerMask);
if (tappedTransform != null) {
return tappedTransform;
}
}
return null;
}
public Transform TappedTransform (Camera cam, int fingerID, int layerMask)
{
if (!m_TouchSensors [fingerID].IsActive || !IsTapped (fingerID)) {
return null;
}
Ray ray;
RaycastHit hit;
ray = cam.ScreenPointToRay (m_TouchSensors [fingerID].Position);
if (Physics.Raycast (ray, out hit, 1000.0f, layerMask)) {
return hit.transform;
}
return null;
}
public T TouchComponent<T> () where T : Component
{
T touchComponent;
touchComponent = null;
for (int i = 0; i < m_TouchSensors.Length; i++) {
touchComponent = TouchComponent<T> (i);
if (touchComponent != null) {
break;
}
}
return touchComponent;
}
public T TouchComponent<T> (Camera cam) where T : Component
{
for (int i = 0; i < m_TouchSensors.Length; i++) {
if (!m_TouchSensors [i].IsActive) {
continue;
}
return TouchComponent<T> (cam, i, ~0);
}
return null;
}
public T TouchComponent<T> (int fingerID) where T : Component
{
return TouchComponent<T> (fingerID, ~0);
}
public T TouchComponent<T> (Camera cam, int fingerID) where T : Component
{
return TouchComponent<T> (cam, fingerID, ~0);
}
public T TouchComponent<T> (int fingerID, int layerMask) where T : Component
{
if (!m_TouchSensors [fingerID].IsActive || !IsTouched (fingerID)) {
return null;
}
T touchComponent;
List<Camera> cams = new List<Camera> ();
foreach (Camera cam in Camera.allCameras) {
cams.Add (cam);
}
cams.Sort ((Camera a, Camera b) => (int)b.depth - (int)a.depth);
touchComponent = null;
for (int i = 0; i < cams.Count; i++) {
touchComponent = TouchComponent<T> (cams [i], fingerID, layerMask);
if (touchComponent != null) {
return touchComponent;
}
}
return null;
}
public T TouchComponent<T> (Camera cam, int fingerID, int layerMask) where T : Component
{
if (cam == null || !m_TouchSensors [fingerID].IsActive || !IsTouched (fingerID)) {
return null;
}
Ray ray;
RaycastHit hit;
ray = cam.ScreenPointToRay (m_TouchSensors [fingerID].Position);
if (Physics.Raycast (ray, out hit, 1000.0f, layerMask)) {
return hit.transform.GetComponent<T> ();
}
return null;
}
void Awake ()
{
if (instance != null && instance != this) {
Destroy (gameObject);
return;
}
int maxTouchCount = this.maxTouchCount;
useMouse = (
useMouse &&
Application.platform != RuntimePlatform.Android &&
Application.platform != RuntimePlatform.IPhonePlayer
);
if (useMouse) {
maxTouchCount += mouseButtonCount;
}
if (m_TouchSensors == null) {
m_TouchSensors = new TouchAndMouse[maxTouchCount];
for (int i = 0; i < m_TouchSensors.Length; i++) {
if (i < this.maxTouchCount) {
m_TouchSensors [i] = new TouchSensor ();
} else {
m_TouchSensors [i] = new MouseTouchSensor ();
}
}
}
}
void Update ()
{
foreach (TouchAndMouse touch in m_TouchSensors) {
touch.InitUpdate ();
}
for (int i = 0; i < Input.touchCount; i++) {
if (Input.touches [i].fingerId >= maxTouchCount) {
continue;
}
m_TouchSensors [Input.touches [i].fingerId].SetTouch (Input.touches [i].fingerId, m_IsActive);
}
if (useMouse) {
for (int i = 0; i < mouseButtonCount; i++) {
if (Input.GetMouseButton (i) || Input.GetMouseButtonUp (i)) {
m_TouchSensors [maxTouchCount + i].SetTouch (i, m_IsActive);
}
}
}
}
}
public class TouchSensor : TouchAndMouse
{
public override void InitUpdate ()
{
IsActive = false;
}
public override void SetTouch (int fingerID, bool isActive)
{
foreach (Touch touch in Input.touches) {
if (touch.fingerId == fingerID) {
m_Touch = touch;
break;
}
}
if (m_Touch.phase == TouchPhase.Began) {
TouchBeganTime = Time.realtimeSinceStartup;
TouchEndTime = TouchBeganTime;
TouchDeltaTime = 0.0f;
BeganPosition = m_Touch.position;
DeltaMovement = Vector2.zero;
Movement = Vector2.zero;
} else if (m_Touch.phase == TouchPhase.Ended) {
TouchEndTime = Time.realtimeSinceStartup;
TouchDeltaTime = TouchEndTime - TouchBeganTime;
Movement += new Vector2 (
DeltaMovement.x * Mathf.Sign (DeltaMovement.x),
DeltaMovement.y * Mathf.Sign (DeltaMovement.y));
MoveDirection = m_Touch.position - BeganPosition;
} else {
DeltaMovement = m_Touch.deltaPosition;
Movement += new Vector2 (
DeltaMovement.x * Mathf.Sign (DeltaMovement.x),
DeltaMovement.y * Mathf.Sign (DeltaMovement.y));
MoveDirection = m_Touch.position - BeganPosition;
}
Phase = m_Touch.phase;
Position = m_Touch.position;
IsActive = isActive;
}
}
public class MouseTouchSensor : TouchAndMouse
{
Vector2 m_LatePosition;
public override void InitUpdate ()
{
IsActive = false;
}
public override void SetTouch (int fingerID, bool isActive)
{
Vector2 mousePosition = new Vector2 (Input.mousePosition.x, Input.mousePosition.y);
if (Input.GetMouseButtonDown (fingerID)) {
TouchBeganTime = Time.realtimeSinceStartup;
TouchEndTime = TouchBeganTime;
TouchDeltaTime = 0.0f;
BeganPosition = mousePosition;
m_LatePosition = mousePosition;
Position = mousePosition;
DeltaMovement = Vector2.zero;
Movement = Vector2.zero;
Phase = TouchPhase.Began;
} else if (Input.GetMouseButtonUp (fingerID)) {
TouchEndTime = Time.realtimeSinceStartup;
TouchDeltaTime = TouchEndTime - TouchBeganTime;
MoveDirection = mousePosition - BeganPosition;
Movement += new Vector2 (
DeltaMovement.x * Mathf.Sign (DeltaMovement.x),
DeltaMovement.y * Mathf.Sign (DeltaMovement.y));
Phase = TouchPhase.Ended;
} else if (Input.GetMouseButton (fingerID)) {
Position = mousePosition;
DeltaMovement = mousePosition - m_LatePosition;
m_LatePosition = mousePosition;
MoveDirection = mousePosition - BeganPosition;
Movement += new Vector2 (
DeltaMovement.x * Mathf.Sign (DeltaMovement.x),
DeltaMovement.y * Mathf.Sign (DeltaMovement.y));
Phase = TouchPhase.Moved;
}
IsActive = isActive;
}
}
public abstract class TouchAndMouse
{
protected Touch m_Touch;
public float TouchBeganTime {
get;
protected set;
}
public float TouchEndTime {
get;
protected set;
}
public float TouchDeltaTime {
get;
protected set;
}
public TouchPhase Phase {
get;
protected set;
}
public Vector2 BeganPosition {
get;
protected set;
}
public Vector2 Position {
get;
protected set;
}
public Vector2 DeltaMovement {
get;
protected set;
}
public Vector2 Movement {
get;
protected set;
}
public Vector2 MoveDirection {
get;
protected set;
}
public bool IsActive {
get;
protected set;
}
public virtual void InitUpdate ()
{
}
public virtual void SetTouch (int fingerID, bool isActive)
{
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment