1.所有2D和3D物体的射线检测。 当检测到 2D 对象时,表明当前存在 UI。 然而,Physics2D.Raycast()和Physics.Raycast()都只能检测包含Collider组件的对象。 普通UI如Image Button等一般光线将无法工作。 EventSystem.current.RaycastAll() 可以检测当前屏幕上所有可检测的对象。 该方法需要构造一个PointerEventData参数并传入检测到的点坐标:
1 PointerEventData pointerData = new PointerEventData (EventSystem.current); 2 pointerData.position = Input.mousePosition; 3 Listresults = new List (); 4 EventSystem.current.RaycastAll (pointerData, results);
2、将PhysicsRaycaster组件挂在3D物体的Camera上,让3D物体上的脚本响应IPointerClickHandler等事件(原理与挂在Canvas上的GraphicRaycaster组件相同)。
当3D对象上有UI时程序开发,它会自动被UI事件拦截,因为通常UI(Camera或overlay)的显示级别高于场景中的3D对象。
这样,只有当你点击UI时,它才会响应UI事件。 如果还想响应3D物体上的事件,只能再次使用射线来检测点击位置是否有3D物体(3D物体一般都有Colliders)。
3.具体参见以下代码
1 void Update ()
2 {
3 if (Input.GetMouseButtonDown (0) || (Input.touchCount > 0 && Input.GetTouch (0).phase == TouchPhase.Began))
4 {
5 #if UNITY_IOS || UNITY_ANDROID
6 if (EventSystem.current.IsPointerOverGameObject (Input.GetTouch (0).fingerId))
7 #else
8 if (EventSystem.current.IsPointerOverGameObject ())
9 #endif
10 Debug.Log ("当前触摸在UI上");
11
12 else
13 Debug.Log ("当前没有触摸在UI上");
14 }
15 }
不过EventSystem.current.IsPointerOverGameObject()只能检测Button等有事件的组件,普通Images等UI无法检测,所以该方法只用在少数简单的按钮和其他交互UI、3D对象之间。 当打开一个大的UI窗口并点击背景图片等非按钮时游戏运营,该判断将无效。
其他:
为了让3D对象响应点击,MonoBehaviour自带了一个消息函数MonoBehaviour.OnMouseDown()。 可以很容易实现,但脚本中最好不要有OnMouseXXX消息处理函数。 此类功能会影响游戏性能。 (当存在这样的函数时unity射线检测耗时,构建包末尾会有黄色警告,表示对性能的影响)
Graphics Raycaster 的 Raycast 是一个虚函数。 您可以编写 Graphics Raycaster 的派生类。 执行默认的 Raycast 操作后,使用自定义图层过滤并移除不需要响应的游戏对象。 这样就只能响应某一层的需求。 在新手指南中unity射线检测耗时,只需设置需要响应特定层的游戏对象即可。
实现ICanvasRaycastFilter接口并将其挂在UI组件上。 当任意UI事件触发时,您可以实现自定义判断,例如:
1 public class CustomRay : MonoBehaviour, ICanvasRaycastFilter 2 { 3 public bool IsRaycastLocationValid(Vector2 screenPoint, Camera eventCamera) 4 { 5 //.... 6 ... 7 return true; 8 //.... 9 ... 10 return false; 11 } 12 }
文章来源:https://mnews.68idc.cn/mobilesys/other/20170905643366.html