summaryrefslogtreecommitdiff
path: root/Runtime/Export/MouseEvents.cs
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2019-08-14 22:50:43 +0800
committerchai <chaifix@163.com>2019-08-14 22:50:43 +0800
commit15740faf9fe9fe4be08965098bbf2947e096aeeb (patch)
treea730ec236656cc8cab5b13f088adfaed6bb218fb /Runtime/Export/MouseEvents.cs
+Unity Runtime codeHEADmaster
Diffstat (limited to 'Runtime/Export/MouseEvents.cs')
-rw-r--r--Runtime/Export/MouseEvents.cs187
1 files changed, 187 insertions, 0 deletions
diff --git a/Runtime/Export/MouseEvents.cs b/Runtime/Export/MouseEvents.cs
new file mode 100644
index 0000000..bd87008
--- /dev/null
+++ b/Runtime/Export/MouseEvents.cs
@@ -0,0 +1,187 @@
+using System;
+using System.Collections;
+using System.Reflection;
+
+namespace UnityEngine
+{
+
+internal class SendMouseEvents
+{
+ struct HitInfo
+ {
+ public GameObject target;
+ public Camera camera;
+
+ public void SendMessage (string name)
+ {
+ target.SendMessage (name, null, SendMessageOptions.DontRequireReceiver);
+ }
+
+ public static implicit operator bool (HitInfo exists)
+ {
+ return exists.target != null && exists.camera != null;
+ }
+
+ public static bool Compare (HitInfo lhs, HitInfo rhs)
+ {
+ return lhs.target == rhs.target && lhs.camera == rhs.camera;
+ }
+ }
+
+ static HitInfo[] m_LastHit = { new HitInfo (), new HitInfo () };
+ static HitInfo[] m_MouseDownHit = { new HitInfo (), new HitInfo () };
+ static RaycastHit2D[] m_MouseRayHits2D = {new RaycastHit2D()};
+
+ [NotRenamed]
+ static void DoSendMouseEvents (int mouseUsed, int skipRTCameras)
+ {
+ HitInfo[] currentHit = { new HitInfo (), new HitInfo () };
+ Vector3 mousePosition = Input.mousePosition;
+ Camera[] cameras = Camera.allCameras;
+
+ // If UnityGUI has the mouse over, we simply don't do any mouse hit detection.
+ // That way, it will appear as if the mouse has missed everything.
+ if (mouseUsed == 0)
+ {
+ foreach (Camera camera in cameras)
+ {
+ // we do not want to check cameras that are rendering to textures, starting with 4.0
+ if (skipRTCameras != 0 && camera.targetTexture != null)
+ continue;
+
+ // Is the mouse inside the cameras viewport?
+ Rect rect = camera.pixelRect;
+ if (!rect.Contains (mousePosition))
+ continue;
+
+ // Did we hit any gui elements?
+ GUILayer layer = (GUILayer)camera.GetComponent (typeof (GUILayer));
+ if (layer)
+ {
+ GUIElement element = layer.HitTest (mousePosition);
+ if (element)
+ {
+ currentHit[0].target = element.gameObject;
+ currentHit[0].camera = camera;
+ }
+ }
+#if ENABLE_PHYSICS || ENABLE_2D_PHYSICS
+ // There is no need to continue if the camera shouldn't be sending out events
+ if ((int)camera.eventMask == 0)
+ continue;
+
+#if ENABLE_PHYSICS
+ // Did we hit any colliders?
+ RaycastHit hit;
+ if (camera.farClipPlane > 0.0f && Physics.Raycast (camera.ScreenPointToRay (mousePosition),
+ out hit, camera.farClipPlane, camera.cullingMask & camera.eventMask & Physics.DefaultRaycastLayers
+ ))
+ {
+ if (hit.rigidbody)
+ {
+ currentHit[1].target = hit.rigidbody.gameObject;
+ currentHit[1].camera = camera;
+ }
+ else
+ {
+ currentHit[1].target = hit.collider.gameObject;
+ currentHit[1].camera = camera;
+ }
+ }
+#endif
+#if ENABLE_2D_PHYSICS
+ // Did we hit any 2D colliders?
+ else if (camera.farClipPlane > 0.0f)
+ {
+ // Did we hit any 2D colliders?
+ if (Physics2D.GetRayIntersectionNonAlloc (camera.ScreenPointToRay (mousePosition),
+ m_MouseRayHits2D, camera.farClipPlane, camera.cullingMask & camera.eventMask & Physics2D.DefaultRaycastLayers) == 1)
+ {
+ currentHit[1].camera = camera;
+ if (m_MouseRayHits2D[0].rigidbody)
+ currentHit[1].target = m_MouseRayHits2D[0].rigidbody.gameObject;
+ else
+ currentHit[1].target = m_MouseRayHits2D[0].collider.gameObject;
+ }
+ }
+#endif
+ else
+ {
+ // We did not hit anything with a raycast from this camera. But our camera
+ // clears the screen and renders on top of whatever was below, thus making things
+ // rendered before invisible. So clear any previous hit we have found.
+ if (camera.clearFlags == CameraClearFlags.Skybox || camera.clearFlags == CameraClearFlags.Color)
+ {
+ currentHit[1].target = null;
+ currentHit[1].camera = null;
+ }
+ }
+#endif
+ }
+ }
+
+ // i=0: CameraGUILayer, i=1: 3D Objects
+ for (int i=0;i<2;i++)
+ SendEvents(i, currentHit[i]);
+ }
+
+ /// <summary>
+ /// Old-style mouse events used prior to the new event system of 4.2.
+ /// </summary>
+
+ static void SendEvents (int i, HitInfo hit)
+ {
+ // Handle MouseDown, MouseDrag, MouseUp
+ bool mouseDownThisFrame = Input.GetMouseButtonDown(0);
+ bool mousePressed = Input.GetMouseButton(0);
+
+ if (mouseDownThisFrame)
+ {
+ if (hit)
+ {
+ m_MouseDownHit[i] = hit;
+ m_MouseDownHit[i].SendMessage("OnMouseDown");
+ }
+ }
+ else if (!mousePressed)
+ {
+ if (m_MouseDownHit[i])
+ {
+ // For button like behavior only fire this event if same as on MouseDown
+ if (HitInfo.Compare(hit, m_MouseDownHit[i]))
+ m_MouseDownHit[i].SendMessage("OnMouseUpAsButton");
+
+ // For backwards compatibility we keep the event name OnMouseUp
+ m_MouseDownHit[i].SendMessage("OnMouseUp");
+ m_MouseDownHit[i] = new HitInfo();
+ }
+ }
+ else if (m_MouseDownHit[i])
+ {
+ m_MouseDownHit[i].SendMessage("OnMouseDrag");
+ }
+
+
+ // Handle MouseOver, MouseEnter, MouseExit
+ if (HitInfo.Compare(hit, m_LastHit[i]))
+ {
+ if (hit)
+ hit.SendMessage("OnMouseOver");
+ }
+ else
+ {
+ if (m_LastHit[i])
+ {
+ m_LastHit[i].SendMessage("OnMouseExit");
+ }
+
+ if (hit)
+ {
+ hit.SendMessage("OnMouseEnter");
+ hit.SendMessage("OnMouseOver");
+ }
+ }
+ m_LastHit[i] = hit;
+ }
+}
+}