CanvasGroup是Unity中用于控制UI的透明度、交互性和渲染顺序的组件。
一、常用属性的解释
1、alpha:控制UI的透明度
类型:float,0.0 ~1.0,
其中 0.0 完全透明,1.0 完全不透明。
通过调整alpha值可以实现UI的淡入淡出效果,可以参考本人的另一篇文章:
Unity功能——设置提示面板的显示与掩藏
2、blocksRaycasts:控制UI是否阻挡射线(Raycasts)
(1)类型:bool,true/false,
(2)true时会阻挡射线,false时不会阻挡射线。
(3)用户不对该UI后面的UI进行射线检测,可将值设置为true;
3、interactable:控制UI是否可交互(如点击、拖动等)
(1)类型:bool,true/false,
(2)true时会响应用户输入,false时将忽略用户输入。
(3)用户不对该UI进行交互,可将值设置为false;
4、ignoreParentGroups:控制UI是否忽略父级CanvasGroup的设置
(1)类型:bool,true/false,
(2)true时将忽略其父级CanvasGroup的alpha和interactable设置,false时会受到父级CanvasGroup的设置影响。
(3)用户要独立控制UI的透明度和交互性,可将值设置为true;
二、组件的alpha属性和UI的alpha属性的异同
1、相同点:
在视觉上是一样的,都可控制UI能不能被用户看到,也仅是控制物体的不透明度;
在交互上,都不会影响UI的交互性,都可正常进行交互事件;
在射线检测上,也都不会改变UI对射线的阻挡特性;
2、不同点:
(1)作用范围不同
直接设置 UI 元素的alpha值,只会影响该单个UI元素的透明度,其父子元素不会受到影响。
而CanvasGroup组件可以控制其所在UI及其所有子对象的透明度。组件所在的UI对象以及它包含的所有子物体(如按钮、文本框等)都会统一改变透明度。
(2)性能影响不同
直接设置单个UI的alpha值,性能开销相对较小,因为只涉及到对单个对象的属性修改。
当使用CanvasGroup时,会影响多个子对象,Unity需要处理更多的渲染和交互状态更新,
性能开销相对较大,尤其是在子对象数量较多的情况下。不过,在大多数正常场景下,这种开销通常是可以接受的。
三、组件的alpha属性和UI的visible属性的异同
1、相同点:
在视觉上是一样的,都可控制UI能不能被用户看到;
2、不同点:
(1)直接设置UI的visible值为false后,UI将完全不响应任何事件;
因为visible为false,背包及其内部子物体都不会被渲染出来,更不会被交互;
(2)而通过设置CanvasGroup组件的alpha值,只是影响视觉效果,不影响事件交互。
故即使aplha值为0,对UI及其子物体的拖拽移动,修改等任何事件都会正常执行。
四、(重点)blocksRaycasts和interactable之间的区别和使用场景
下面提到的自身,包括挂载组件的UI以及UI内部的其他子对象。
1、异同
相同:都会影响UI自身的交互;
不同:
Interactable是影响(自身的)输入事件,影响交互状态;
BlocksRaycasts是影响(自身和自身以外后面的UI的)射线事件,影响射线检测状态。
2、使用环境
以背包面板为例,
(1)状态说明如下:
1)仅背包上挂载CanvasGroup组件;
2)可通过键盘输入事件,往背包内部物品格里增减物品;
3)背包、物品格里的物品、背包后面的物品X都能进行鼠标点击移动操作时,
4)点击重叠处,通常会优先处理最上层的元素:物品>物品格>背包>物品X;
4)由于背包的visible值为false,完全不响应任何事件,
而CanvasGroup组件的alpha值只影响视觉效果,不影响任何用户事件。
若visible为false,无论CanvasGroup设置什么样,物体X怎么也不会被背包遮挡,能被射线检测到,可被鼠标拖动。
故这里默认背包的visible值为true,通过CanvasGroup的alpha值控制背包显示掩藏。
(2)情况分析:
1)Interactable为true,BlocksRaycasts为true:
Interactable为true,
表示背包及子物体的交互事件可正常执行,鼠标键盘事件背包及子物体都可被接收。
blocksRaycasts为true:
在检测鼠标点击时,射线会首先命中背包面板,鼠标点击事件会优先被背包面板接收并处理,而不会触发后面物体 X 的点击拖动事件。
无论alpha值是不是为0,背包面板是不是不可见,都会认为背包面板仍然存在并会阻挡射线,交互逻辑上优先响应背包面板:
故鼠标点击背包/物品X:
背包面板可被鼠标拖动;背包里的物品也可以正常被鼠标移动;
也可正常通过键盘事件,往内部物品格里进行增减物品;
物体X被背包遮挡,不会被射线检测到,无法被鼠标拖动;
2)Interactable为true,BlocksRaycasts为false:
interactable为true,
表明背包及其子元素,理论上可以接受交互事件;
但blocksRaycasts为false,
背包面板不会阻挡射线检测,射线会直接穿透背包面板,命中其后面的物体X。
无论alpha值是不是为1,背包面板是不是可见,交互逻辑上只响应物体X的射线检测事件,
不过键盘的事件不是由射线检测判断触发,背包里的物品正常接收键盘事件;
故鼠标点击背包/物品X:
背包面板不能被鼠标拖动;背包里的物品无法被鼠标移动;
但可正常通过键盘事件,往内部物品格里进行增减物品;
物体X不会被背包遮挡,可以被射线检测到,被鼠标拖动;
3)Interactable为false,BlocksRaycasts为true:
blocksRaycasts为true
在检测鼠标点击时,射线会首先命中背包面板,鼠标点击事件会优先被背包面板接收并处理,而不会触发后面物体 X 的点击拖动事件。
但Interactable为false
背包及其子元素的交互层面被设置为不可用状态,背包上的任何交互事件都不会被接受触发。
因此背包子物体的键盘事件不会被触发;同时即使背包及其子物体接收了鼠标的射线检测,也不会触发鼠标事件。
故鼠标点击背包/物品X:
背包面板不能被鼠标拖动;背包里的物品无法被鼠标移动;
通过键盘事件,也不能往内部物品格里进行增减物品;
物体X会被背包遮挡,不会被射线检测到,无法被鼠标拖动;
4)Interactable为false,BlocksRaycasts为false:
blocksRaycasts为false
背包面板不会阻挡射线检测,射线会直接穿透背包面板,命中其后面的物体X。交互逻辑上只响应物体X的射线检测事件。
Interactable为false
背包及其子元素的交互层面被设置为不可用状态,背包上的任何交互事件都不会被接受触发。
因此背包和子物体的鼠标事件,以及子物体的键盘事件都不会被触发。
故鼠标点击背包/物品X:
背包面板不能被鼠标拖动;背包里的物品无法被鼠标移动;
通过键盘事件,也不能往内部物品格里进行增减物品;
物体X不会被背包遮挡,可以被射线检测到,被鼠标拖动;