Unity 的 CanvasGroup 可以理解成一个“UI 父节点控制器”:挂在一个 GameObject 上后,会统一影响它下面的 UI 的透明度、交互和射线检测。官方目前提供 4 个核心参数:Alpha、Interactable、Blocks Raycasts、Ignore Parent Groups。
1. Alpha
Alpha = 1
完全不透明。
Alpha = 0.5
整体半透明。
Alpha = 0
视觉上完全不可见。
它会影响子节点 UI 的最终透明度。
例如:
Panel CanvasGroup Alpha = 0.5
├── Image Alpha = 1
└── Text Alpha = 1
最终:
Image Alpha = 0.5
Text Alpha = 0.5
如果存在多层 CanvasGroup,则会相乘:
父 CanvasGroup Alpha = 0.5
子 CanvasGroup Alpha = 0.5
最终 Alpha = 0.5 × 0.5 = 0.25
这也是 CanvasGroup 非常适合做 UI Fade In / Fade Out 的原因。
例如:
canvasGroup.alpha = 0f;
// 淡入
canvasGroup.alpha = 1f;
2. Interactable
这个参数控制:
UI 是否允许交互。
例如:
Interactable = true
下面的:
Button
Toggle
Slider
InputField
等 UI 可以正常交互。
如果:
Interactable = false
那么下面的 UI 会处于不可交互状态。
例如:
Panel
└── CanvasGroup
├── Button A
├── Button B
└── Button C
设置:
canvasGroup.interactable = false;
相当于把这一整组 UI 暂时设成不可操作。
非常常见的用法
比如游戏暂停菜单:
pausePanel.interactable = false;
或者 UI 动画过程中:
打开动画
↓
interactable = false
↓
播放动画
↓
动画结束
↓
interactable = true
避免玩家在动画过程中疯狂点击。
3. Blocks Raycasts
这个参数特别容易和 Interactable 搞混。
它控制的是:
这个 UI 是否参与 UI Raycast。
也就是:
鼠标点击
触摸
Pointer Event
GraphicRaycaster
是否能够“碰到”这一组 UI。
Blocks Raycasts = true
默认情况下:
Blocks Raycasts = true
这个 UI 会参与 Raycast。
例如:
Button
可以挡住它后面的 UI。
Blocks Raycasts = false
表示:
这个 UI 不参与 UI Raycast
比如你有:
Canvas
├── Background
└── Effect
Effect 只是一个装饰性的 Image:
Effect CanvasGroup
Blocks Raycasts = false
那么点击这个 Effect 时,Raycast 可以继续穿过去,点击下面的 UI。
这在游戏 UI 中非常常见:
UI特效
玻璃效果
遮罩装饰
粒子UI
纯视觉Image
通常应该:
Blocks Raycasts = false
4. Interactable 和 Blocks Raycasts 的区别
这个是 CanvasGroup 最值得理解的地方。
可以简单记:
| 参数 | 作用 |
|---|---|
Interactable | 我能不能操作它 |
Blocks Raycasts | 鼠标/触摸能不能碰到它 |
例如:
情况 A
Interactable = false
Blocks Raycasts = true
表现:
点击
↓
这个 UI 可以被 Raycast 检测到
↓
但是 UI 自己不能交互
↓
通常不会让点击穿透到下面的 UI
所以它适合:
“我现在不能操作,但我仍然要挡住下面的 UI。”
情况 B
Interactable = false
Blocks Raycasts = false
表现:
点击
↓
直接穿过这个 UI
↓
下面的 UI 可以收到点击
适合:
“这个 UI 只是视觉上的东西,不应该影响点击。”
5. Ignore Parent Groups
这个参数稍微高级一点。
假设:
Root CanvasGroup
Alpha = 0
Interactable = false
↓
Child CanvasGroup
Ignore Parent Groups = false
默认情况下,Child 会受到 Parent 的 CanvasGroup 影响。
所以:
Parent Alpha = 0
那么 Child 也会受到影响。
如果:
Child Ignore Parent Groups = true
那么 Child CanvasGroup 会忽略父级 CanvasGroup 的相关影响。官方文档也特别说明了嵌套 CanvasGroup 时该属性用于忽略父组影响。
可以理解成:
父 CanvasGroup
↓
影响我?
IgnoreParentGroups = false
↓
是
IgnoreParentGroups = true
↓
不管你
6. 最常见的实际组合
作为 Unity UI 程序开发,实际项目里你可以重点记下面几种。
普通可交互 UI
Alpha = 1
Interactable = true
Blocks Raycasts = true
Ignore Parent Groups = false
隐藏 UI
Alpha = 0
Interactable = false
Blocks Raycasts = false
注意:
Alpha = 0 不等于不参与点击。
如果:
Alpha = 0
Blocks Raycasts = true
这个 UI 虽然看不见,但仍可能挡住下面的 UI。
这是 UI 中非常经典的 Bug。
UI 淡出过程中禁止点击
Alpha = 0.5
Interactable = false
Blocks Raycasts = false
纯视觉 UI
比如:
UI特效
Bloom模拟
装饰Image
动态背景
一般:
Alpha = 1
Interactable = false
Blocks Raycasts = false
7. 一个非常实用的 UI 状态设计
比如你的游戏有一个:
LoadingPanel
可以这样控制:
public void ShowLoading()
{
canvasGroup.alpha = 1f;
canvasGroup.interactable = true;
canvasGroup.blocksRaycasts = true;
}
public void HideLoading()
{
canvasGroup.alpha = 0f;
canvasGroup.interactable = false;
canvasGroup.blocksRaycasts = false;
}
这样:
显示 Loading
↓
Alpha = 1
↓
挡住下面 UI
↓
玩家无法操作下面 UI
隐藏:
Alpha = 0
↓
不参与 Raycast
↓
下面 UI 恢复点击
8. 我建议你直接记这个关系
CanvasGroup
│
┌───────────┼───────────┐
↓ ↓ ↓
Alpha Interactable Blocks Raycasts
│ │ │
看不看见 能不能操作 能不能被点到
再加一个:
Ignore Parent Groups
↓
是否无视父 CanvasGroup
所以一句话:
Alpha 管“看不看得见”,Interactable 管“能不能操作”,Blocks Raycasts 管“点不点得到/挡不挡点击”,Ignore Parent Groups 管“要不要吃父级 CanvasGroup 的影响”。
另外一个很重要的点是:CanvasGroup.enabled = false 和 Interactable = false 不是一回事。CanvasGroup 本身继承自 Behaviour,禁用组件与把 UI 设置成不可交互属于不同层面的行为。
如果你是在做 Unity 游戏 UI,我还可以继续给你讲一个更容易踩坑的主题:CanvasGroup + Button + EventSystem 到底是怎么进行 Raycast 和点击传递的,把 Interactable / BlocksRaycasts / GraphicRaycaster / Raycast Target 四者一次性理清。