[LuaInterface.NoToLua]static public bool Raycast (Vector3 inPos) { for (int i = 0; i < list.size; ++i) { UICamera cam = list.buffer[i]; // Skip inactive scripts if (!cam.enabled || !NGUITools.GetActive(cam.gameObject)) continue; // Convert to view space currentCamera = cam.cachedCamera; #if !UNITY_4_7 && !UNITY_5_0 && !UNITY_5_1 && !UNITY_5_2 if (currentCamera.targetDisplay != 0) continue; #endif Vector3 pos = currentCamera.ScreenToViewportPoint(inPos); if (float.IsNaN(pos.x) || float.IsNaN(pos.y)) continue; // If it's outside the camera's viewport, do nothing if (pos.x < 0f || pos.x > 1f || pos.y < 0f || pos.y > 1f) continue; // Cast a ray into the screen Ray ray = currentCamera.ScreenPointToRay(inPos); // Raycast into the screen int mask = currentCamera.cullingMask & (int)cam.eventReceiverMask; float dist = (cam.rangeDistance > 0f) ? cam.rangeDistance : currentCamera.farClipPlane - currentCamera.nearClipPlane; if (cam.eventType == EventType.World_3D) { lastWorldRay = ray; #if UNITY_4_7 if (Physics.Raycast(ray, out lastHit, dist, mask)) #else if (Physics.Raycast(ray, out lastHit, dist, mask, QueryTriggerInteraction.Ignore)) #endif { lastWorldPosition = lastHit.point; mRayHitObject = lastHit.collider.gameObject; if (!cam.eventsGoToColliders) { var rb = mRayHitObject.gameObject.GetComponentInParent<Rigidbody>(); if (rb != null) mRayHitObject = rb.gameObject; } return true; } continue; } else if (cam.eventType == EventType.UI_3D) { #if UNITY_4_7 RaycastHit[] mRayHits = Physics.RaycastAll(ray, dist, mask); var hitCount = mRayHits.Length; #else if (mRayHits == null) mRayHits = new RaycastHit[50]; var hitCount = Physics.RaycastNonAlloc(ray, mRayHits, dist, mask, QueryTriggerInteraction.Collide); #endif if (hitCount > 1) { for (int b = 0; b < hitCount; ++b) { GameObject go = mRayHits[b].collider.gameObject; #if UNITY_5_5_OR_NEWER UnityEngine.Profiling.Profiler.BeginSample("Editor-only GC allocation (GetComponent)"); UIWidget w = go.GetComponent<UIWidget>(); UnityEngine.Profiling.Profiler.EndSample(); #else Profiler.BeginSample("Editor-only GC allocation (GetComponent)"); UIWidget w = go.GetComponent<UIWidget>(); Profiler.EndSample(); #endif if (w != null) { if (!w.isVisible) continue; if (w.hitCheck != null && !w.hitCheck(mRayHits[b].point)) continue; } else { UIRect rect = NGUITools.FindInParents<UIRect>(go); if (rect != null && rect.finalAlpha < 0.001f) continue; } mHit.depth = NGUITools.CalculateRaycastDepth(go); if (mHit.depth != int.MaxValue) { mHit.hit = mRayHits[b]; mHit.point = mRayHits[b].point; mHit.go = mRayHits[b].collider.gameObject; mHits.Add(mHit); } } mHits.Sort(delegate(DepthEntry r1, DepthEntry r2) { return r2.depth.CompareTo(r1.depth); }); for (int b = 0; b < mHits.size; ++b) { #if UNITY_FLASH if (IsVisible(mHits.buffer[b])) #else if (IsVisible(ref mHits.buffer[b])) #endif { lastHit = mHits[b].hit; mRayHitObject = mHits[b].go; lastWorldRay = ray; lastWorldPosition = mHits[b].point; mHits.Clear(); return true; } } mHits.Clear(); } else if (hitCount == 1) { GameObject go = mRayHits[0].collider.gameObject; #if UNITY_5_5_OR_NEWER UnityEngine.Profiling.Profiler.BeginSample("Editor-only GC allocation (GetComponent)"); UIWidget w = go.GetComponent<UIWidget>(); UnityEngine.Profiling.Profiler.EndSample(); #else Profiler.BeginSample("Editor-only GC allocation (GetComponent)"); UIWidget w = go.GetComponent<UIWidget>(); Profiler.EndSample(); #endif if (w != null) { if (!w.isVisible) continue; if (w.hitCheck != null && !w.hitCheck(mRayHits[0].point)) continue; } else { UIRect rect = NGUITools.FindInParents<UIRect>(go); if (rect != null && rect.finalAlpha < 0.001f) continue; } if (IsVisible(mRayHits[0].point, mRayHits[0].collider.gameObject)) { lastHit = mRayHits[0]; lastWorldRay = ray; lastWorldPosition = mRayHits[0].point; mRayHitObject = lastHit.collider.gameObject; return true; } } continue; } else if (cam.eventType == EventType.World_2D) { if (m2DPlane.Raycast(ray, out dist)) { var point = ray.GetPoint(dist); var c2d = Physics2D.OverlapPoint(point, mask); if (c2d) { lastWorldPosition = point; mRayHitObject = c2d.gameObject; if (!cam.eventsGoToColliders) { Rigidbody2D rb = FindRootRigidbody2D(mRayHitObject.transform); if (rb != null) mRayHitObject = rb.gameObject; } return true; } } continue; } else if (cam.eventType == EventType.UI_2D) { if (m2DPlane.Raycast(ray, out dist)) { lastWorldPosition = ray.GetPoint(dist); #if UNITY_4_7 Collider2D[] mOverlap = Physics2D.OverlapPointAll(lastWorldPosition, mask); var hitCount = mOverlap.Length; #else if (mOverlap == null) mOverlap = new Collider2D[50]; var hitCount = Physics2D.OverlapPointNonAlloc(lastWorldPosition, mOverlap, mask); #endif if (hitCount > 1) { for (int b = 0; b < hitCount; ++b) { GameObject go = mOverlap[b].gameObject; #if UNITY_5_5_OR_NEWER UnityEngine.Profiling.Profiler.BeginSample("Editor-only GC allocation (GetComponent)"); UIWidget w = go.GetComponent<UIWidget>(); UnityEngine.Profiling.Profiler.EndSample(); #else Profiler.BeginSample("Editor-only GC allocation (GetComponent)"); UIWidget w = go.GetComponent<UIWidget>(); Profiler.EndSample(); #endif if (w != null) { if (!w.isVisible) continue; if (w.hitCheck != null && !w.hitCheck(lastWorldPosition)) continue; } else { UIRect rect = NGUITools.FindInParents<UIRect>(go); if (rect != null && rect.finalAlpha < 0.001f) continue; } mHit.depth = NGUITools.CalculateRaycastDepth(go); if (mHit.depth != int.MaxValue) { mHit.go = go; mHit.point = lastWorldPosition; mHits.Add(mHit); } } mHits.Sort(delegate(DepthEntry r1, DepthEntry r2) { return r2.depth.CompareTo(r1.depth); }); for (int b = 0; b < mHits.size; ++b) { #if UNITY_FLASH if (IsVisible(mHits.buffer[b])) #else if (IsVisible(ref mHits.buffer[b])) #endif { mRayHitObject = mHits[b].go; mHits.Clear(); return true; } } mHits.Clear(); } else if (hitCount == 1) { var go = mOverlap[0].gameObject; #if UNITY_5_5_OR_NEWER UnityEngine.Profiling.Profiler.BeginSample("Editor-only GC allocation (GetComponent)"); var w = go.GetComponent<UIWidget>(); UnityEngine.Profiling.Profiler.EndSample(); #else Profiler.BeginSample("Editor-only GC allocation (GetComponent)"); var w = go.GetComponent<UIWidget>(); Profiler.EndSample(); #endif if (w != null) { if (!w.isVisible) continue; if (w.hitCheck != null && !w.hitCheck(lastWorldPosition)) continue; } else { var rect = NGUITools.FindInParents<UIRect>(go); if (rect != null && rect.finalAlpha < 0.001f) continue; } if (IsVisible(lastWorldPosition, go)) { mRayHitObject = go; return true; } } } continue; } } return false; }
调用参数 inPos 为屏幕坐标
文章评论