UGUI射线穿透问题解决方案

unity项目里3D场景中如果有用到射线的,鼠标点击UI会发生UI会被穿透,导致3D场景里的射线触发。 举个例子:下面场景里,在3D场景里点击地面人物(红色的cube)会移动到点击的地方,现在有个button(下图中“显示游戏介绍”按钮)重叠在地面上,当点击按钮时会显示出游戏介绍的界面,但同时人物也会移动到点击的地方(这不是我们预期的效果)

运行cube默认位置:
 


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


这种问题的原因就是当点击鼠标时射线穿透了UI按钮导致了3D场景的射线触发。
具体原理参考网上这篇文章:http://www.tuicool.com/articles/yy2aA3E
这里我只讲实现功能方法
直接上源码(注释很全面):
[C#]  纯文本查看  复制代码
?
 
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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:
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值