0
点赞
收藏
分享

微信扫一扫

UGUI射线穿透问题解决方案

木匠0819 2023-01-05 阅读 108


在​​unity​​项目里3D场景中如果有用到射线的,鼠标点击UI会发生UI会被穿透,导致3D场景里的射线触发。

举个例子:下面场景里,在3D场景里点击地面人物(红色的cube)会移动到点击的地方,现在有个button(下图中“显示游戏介绍”按钮)重叠在地面上,当点击按钮时会显示出游戏介绍的界面,但同时人物也会移动到点击的地方(这不是我们预期的效果) 。



运行cube默认位置:


 




当点击按钮时候cube的位置:


 




这种​​问题​​的原因就是当点击鼠标时射线穿透了UI按钮导致了3D场景的射线触发。


具体原理参考网上这篇文章:http://www.tuicool.com/articles/yy2aA3E


这里我只讲实现功能方法


直接上源码(注释很全面):

纯文本查看  复制代码


using
UnityEngine;


using
System.Collections;


using
UnityEngine.UI;


using
UnityEngine.EventSystems;


using
System.Collections.Generic;





//该代码实现,在地面上一个位置点击鼠标,player就会慢慢移动到点击的位置


public
class
personmove : MonoBehaviour


{



int
moveSpeed = 500;
//player移动速度



public
Transform player;
//定义一个人物的Transform



private
Vector3 endposition, startpos;






//下面是用来UI事件和射线



EventSystem eventSystem;



GraphicRaycaster RaycastInCanvas;
//Canvas上有这个组件






void
Start()



{



RaycastInCanvas =
this
.gameObject.GetComponent<GraphicRaycaster>();
//这个脚本要绑定到Canvas



endposition = player.transform.position;






}






void
Update()



{



if
(CheckGuiRaycastObjects())
return
;
//如果射线检测到UI上直接返回









if
(Input.GetMouseButtonUp(0))



{
//LeftMouse是在inputManager中设置的,左键值为mouse 0



PlayerMove();



}






if
(endposition != player.transform.position)



{



player.position = Vector3.MoveTowards(player.position, endposition, Time.deltaTime * moveSpeed);



}



}






bool
CheckGuiRaycastObjects()
//测试UI射线



{



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;



}






//人物移动方法



void
PlayerMove()



{



Vector3 cursorScreenPosition = Input.mousePosition;
//鼠标在屏幕上的位置



Ray ray = Camera.main.ScreenPointToRay(cursorScreenPosition);
//在鼠标所在的屏幕位置发出一条射线(暂名该射线为x射线)



RaycastHit hit;






if
(Physics.Raycast(ray,
out
hit, 1000))



{



if
(hit.collider.gameObject.tag ==
"Terrain"
)



{
//设置地形Tag为Terrain



endposition = hit.point;

​​​​






注意:GraphicRaycaster组件默认在canvas上就有的,所以将上面脚本绑定到Canvas上就OK。




然后运行看到当点击按钮时3D场景不会受到影响了。


Look:


 


举报

相关推荐

0 条评论