unity區分點擊在3D物體還是2D UI上


當場景中的3D物體需要響應點擊,但同時有UI顯示時,存在判斷點擊是在3D物體上還是UI上的問題,辦法如下:

  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     List<RaycastResult> results = new List<RaycastResult> ();
4     EventSystem.current.RaycastAll (pointerData, results);

  2. 在3D物體的Camera上掛上PhysicsRaycaster組件即可讓3D物體上的腳本響應IPointerClickHandler等事件了(原理同Canvas上都掛有GraphicRaycaster組件一下)。

  當3D物體之上有UI時則會自動被UI事件所攔截,因為一般UI的顯示級別(Camera或overlay)是高於場景中的3D物體的。

  這樣就當點擊在UI上時只響應UI事件了,如果同時也要響應3D物體上的事件則只能再次用射線檢測點擊處是否有3D物體(3D物體一般都有Collider)。

  3. 詳見www.xuanyusong.com/archives/3327,如下代碼

 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 ()只能檢測到有event存在的組件如Button等,普通Image等UI是不能被檢測的,故該方法僅用於簡單幾個按鈕等可交互的UI與3D物體間的判斷,當一個大的UI窗口打開時點擊在非按鈕上如背景圖時則失效。

另:

  讓3D物體響應點擊有個MonoBehaviour自帶的消息函數MonoBehaviour.OnMouseDown()可簡單實現,但腳本中最好不要有OnMouseXXX的消息處理函數,此類函數會影響游戲性能。(當存在此類函數時build打包結束時有黃色警告提示性能影響)

  Graphics Raycaster的Raycast是個虛函數,可以寫個Graphics Raycaster的派生類,在默認的Raycast操作執行完以后,用自定義的layer進行篩選,把不需要響應的gameobject去掉。這樣就可以實現只響應某個layer的需求了。新手引導中只要把需要響應的gameobject設置為特定layer就行了。

  實現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 }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM