最近slg項目中有個需求,場景中有地塊,給武將上陣,同時支持拖動,點擊等基本操作,同時又要打開UI替換武將,需要處理點擊穿透的問題
需求點:
1.點擊地塊,打開UI,但是不能點穿導(dǎo)致再次打開(其他辦法也行不在這討論);
2.打開UI,阻擋射線點擊,和第一點需求差不多
3.Canvas Group只能解決 讓射線響應(yīng) UI不被響應(yīng)的需求,而不是UI開啟時射線不響應(yīng)的需求
場景中點擊需要打開對應(yīng)UI,操作一系列上陣創(chuàng)模等功能,但是打開UI的同時,點擊到場景中這些碰撞盒,會持續(xù)響應(yīng),UI上BG image raycasttarget 并不能阻擋射線檢測,這時需要代碼中做一系列操作.
1.首先UI父物體上添加GraphicRaycaster組件,我這里mask只選了UI,其他不知道,沒測試過,
2.?聲明各種變量并找到
private GraphicRaycaster RaycastInCanvas;
private EventSystem eventSystem;
3.前任程序的做法是在Update中通過射線檢測及完成各種需求
主要做法是Input.GetMouseButtonDown(0) 點擊時在判斷,增加下列代碼
private bool CheckUiRaycastObjects()
? ? {
? ? ? ? PointerEventData eventData = new PointerEventData(eventSystem);
? ? ? ? eventData.pressPosition = Input.mousePosition;
? ? ? ? eventData.position = Input.mousePosition;
? ? ? ? List<RaycastResult> list = new List<RaycastResult>();
? ? ? ? RaycastInCanvas.Raycast(eventData, list);
? ? ? ? //Debug.Log(list.Count);
? ? ? ? return list.Count > 0;
? ? }
原理大概就是點擊的時候判斷下是否有UI層并返回響應(yīng)UI層raycasttarget的組件個數(shù),
這個數(shù)量是根據(jù)窗口 MaskBG蒙板上 raycasttarget 是否開啟來判斷
這里順便說一句,由于項目需求,我們這里非全屏UI一般都有層半透mask(全屏是BG),這個會開啟raycasttarget選項,簡單粗暴防點穿,其他的除了button 超鏈接文本 rawimag在模型展示的時候會開啟,其余都是關(guān)閉狀態(tài),否則有一定檢測消耗,具體可以看米忽悠大佬整理的,這里不討論
上面的代碼就很簡單 如果true 說明有UI層級擋住,ray射線相關(guān)操作失效,UI層正常,
false就說明沒UI阻擋. 暫時就說到這里
分割線
今天測試報了個bug,還是點穿了,是因為我們ui分了很多層
之前加了GraphicRaycaster 的在main層,但是pop層也有公用窗口,不可能這個公用窗口加上GraphicRaycaster ,所以上面的方法不行,被點穿,參考了這位兄弟的文章,解決了,具體的可以看他的文章解決,大概原理就是先判斷手指數(shù)量,需要注意pc和真機的區(qū)別