using System.Collections.Generic; using UnityEngine.UI; namespace UnityEngine.EventSystems { //c 投射3D物体的相机挂这个脚本 /// /// Simple event system using physics raycasts. /// [AddComponentMenu("Event/Physics Raycaster")] [RequireComponent(typeof(Camera))] public class PhysicsRaycaster : BaseRaycaster { /// /// Const to use for clarity when no event mask is set /// protected const int kNoEventMaskSet = -1; protected Camera m_EventCamera; /// /// Layer mask used to filter events. Always combined with the camera's culling mask if a camera is used. /// [SerializeField] protected LayerMask m_EventMask = kNoEventMaskSet; protected PhysicsRaycaster() {} public override Camera eventCamera { get { if (m_EventCamera == null) m_EventCamera = GetComponent(); return m_EventCamera ?? Camera.main; } } /// /// Depth used to determine the order of event processing. /// public virtual int depth { get { return (eventCamera != null) ? (int)eventCamera.depth : 0xFFFFFF; } } /// /// Event mask used to determine which objects will receive events. /// public int finalEventMask { get { return (eventCamera != null) ? eventCamera.cullingMask & m_EventMask : kNoEventMaskSet; } } /// /// Layer mask used to filter events. Always combined with the camera's culling mask if a camera is used. /// public LayerMask eventMask { get { return m_EventMask; } set { m_EventMask = value; } } protected void ComputeRayAndDistance(PointerEventData eventData, out Ray ray, out float distanceToClipPlane) { ray = eventCamera.ScreenPointToRay(eventData.position); // compensate far plane distance - see MouseEvents.cs float projectionDirection = ray.direction.z; // ray.direction是归一化了的 distanceToClipPlane = Mathf.Approximately(0.0f, projectionDirection) ? Mathf.Infinity : Mathf.Abs((eventCamera.farClipPlane - eventCamera.nearClipPlane) / projectionDirection); } public override void Raycast(PointerEventData eventData, List resultAppendList) { // Cull ray casts that are outside of the view rect. (case 636595) if (eventCamera == null || !eventCamera.pixelRect.Contains(eventData.position)) return; // 根据触摸数据拿到射线 Ray ray; float distanceToClipPlane; ComputeRayAndDistance(eventData, out ray, out distanceToClipPlane); if (ReflectionMethodsCache.Singleton.raycast3DAll == null) return; var hits = ReflectionMethodsCache.Singleton.raycast3DAll(ray, distanceToClipPlane, finalEventMask); if (hits.Length > 1) System.Array.Sort(hits, (r1, r2) => r1.distance.CompareTo(r2.distance)); if (hits.Length != 0) { for (int b = 0, bmax = hits.Length; b < bmax; ++b) { var result = new RaycastResult { gameObject = hits[b].collider.gameObject, module = this, distance = hits[b].distance, worldPosition = hits[b].point, worldNormal = hits[b].normal, screenPosition = eventData.position, index = resultAppendList.Count, sortingLayer = 0, sortingOrder = 0 }; resultAppendList.Add(result); } } } } }