[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 为屏幕坐标
文章评论