using System; using UnityEngine; namespace MyUtility { public class UtilityClickTouchDetector : MonoBehaviour { private enum ECursorState { DOWN_FRAME = 0, UP_FRAME = 1, HELD = 2 } public Action m_onClick; private Collider m_collider; private Camera m_camera; private bool m_isMouseDown; private bool m_isHeldDown; public Collider ColliderInstance { get { return m_collider; } set { m_collider = value; } } public Camera CameraInstance { get { return m_camera; } set { m_camera = value; } } private void Start() { if (m_collider == null) { m_collider = GetComponent(); if (m_collider == null) { Debug.LogError("UtilityClickTouchDetector: could not find a collider!"); base.enabled = false; } } if (m_camera == null) { m_camera = Camera.main; if (m_camera == null) { Debug.LogError("UtilityClickTouchDetector: could not find a camera!"); base.enabled = false; } } } private void Update() { if (m_collider != null && m_camera != null) { bool mouseButton = Input.GetMouseButton(0); if (mouseButton || m_isMouseDown) { ECursorState p_state = ((!mouseButton) ? ECursorState.UP_FRAME : (m_isMouseDown ? ECursorState.HELD : ECursorState.DOWN_FRAME)); RaycastCursor(Input.mousePosition, p_state); m_isMouseDown = mouseButton; } Touch[] touches = Input.touches; for (int i = 0; i < touches.Length; i++) { ECursorState p_state2; switch (touches[i].phase) { case TouchPhase.Began: p_state2 = ECursorState.DOWN_FRAME; break; case TouchPhase.Ended: p_state2 = ECursorState.UP_FRAME; break; case TouchPhase.Moved: case TouchPhase.Stationary: p_state2 = ECursorState.HELD; break; default: continue; } RaycastCursor(touches[i].position, p_state2); } } else if (m_collider == null) { Debug.LogError("UtilityClickTouchDetector: Update: lost reference to collider!"); base.enabled = false; } else { Debug.LogError("UtilityClickTouchDetector: Update: lost reference to camera!"); base.enabled = false; } } private void OnDestroy() { m_onClick = null; } private void RaycastCursor(Vector3 p_screenPos, ECursorState p_state) { RaycastHit hitInfo; if (m_collider.Raycast(m_camera.ScreenPointToRay(p_screenPos), out hitInfo, float.MaxValue)) { if (m_isHeldDown) { switch (p_state) { case ECursorState.DOWN_FRAME: m_isHeldDown = true; break; case ECursorState.UP_FRAME: m_isHeldDown = false; if (m_onClick != null) { m_onClick(); } break; } } else if (p_state == ECursorState.DOWN_FRAME) { m_isHeldDown = true; } } else if (m_isHeldDown && (p_state == ECursorState.DOWN_FRAME || p_state == ECursorState.UP_FRAME)) { m_isHeldDown = false; } } } }