Last active
November 6, 2018 07:59
-
-
Save nir1082/9ce1ff6e3b521168a36e55bd26385fab to your computer and use it in GitHub Desktop.
[Unity] オレオレTouchManager
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 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