OccluderInstance3D
2026/4/14大约 4 分钟
最后同步日期:2026-04-15 | Godot 官方原文 — OccluderInstance3D
OccluderInstance3D
节点继承关系
继承自 Node3D
| 类型 | 名称 | 说明 |
|---|---|---|
| 属性 | Position | 本地位置(X / Y / Z) |
| 属性 | GlobalPosition | 全局位置 |
| 属性 | Rotation | 旋转角度(欧拉角,弧度) |
| 属性 | Scale | 缩放比例 |
| 属性 | TopLevel | 是否脱离父节点的变换 |
| 方法 | LookAt() | 朝向目标点 |
| 方法 | ToGlobal() | 本地坐标转全局坐标 |
| 方法 | ToLocal() | 全局坐标转本地坐标 |
| 方法 | RotateX/Y/Z() | 绕指定轴旋转 |
继承自 Node
| 类型 | 名称 | 说明 |
|---|---|---|
| 属性 | Name | 节点名称 |
| 属性 | ProcessMode | 处理模式(始终 / 暂停时 / 仅编辑器) |
| 属性 | ProcessPriority | 处理优先级,数字越小越先执行 |
| 信号 | ready | 节点进入场景树并准备就绪 |
| 信号 | tree_entered | 节点进入场景树 |
| 信号 | tree_exited | 节点完全离开场景树 |
| 方法 | GetNode<T>() | 按路径获取子节点 |
| 方法 | AddChild() | 添加子节点 |
| 方法 | RemoveChild() | 移除子节点 |
| 方法 | QueueFree() | 帧结束后释放节点 |
| 方法 | GetParent() | 获取父节点 |
定义
遮挡体节点——告诉渲染引擎"这个物体挡住了后面的东西,后面的东西不需要画了"。通过跳过被遮挡物体的渲染,显著提升游戏性能。
打个比方:想象你站在一栋大楼前面,你看不到大楼后面的东西。如果画家把大楼后面的景物也画出来,就白费功夫了。OccluderInstance3D 就是告诉渲染引擎"这面墙后面不用画了",从而节省性能。
使用频率:★★ 偶尔使用——大型场景优化时使用。
节点用途
- 遮挡大型建筑物后面的物体,减少不必要的渲染
- 在室内场景中,墙壁遮挡远处的房间
- 提升大场景的帧率(FPS)
使用场景
典型场景
- 城市/开放世界:高楼遮挡背后的街道和建筑
- 室内关卡:墙壁遮挡隔壁房间
- 隧道/洞穴:隧道壁遮挡隧道深处
不适用场景
- 小型场景(物体少,不需要优化)
- 物体是透明的(透明物体不能做遮挡体)
- 2D 游戏 → 不支持
常用节点搭配
| 搭配节点 | 用途 | 必需? |
|---|---|---|
| Occluder3D 资源 | 定义遮挡体的形状 | 必需 |
典型节点树:
City (Node3D)
├── Building (MeshInstance3D)
├── OccluderInstance3D ← 建筑的遮挡体
└── Player生效必备素材/资源
| 资源 | 类型 | 说明 |
|---|---|---|
| Occluder3D | Occluder3D | 赋给 occluder 属性,定义遮挡体的形状(通常用简化版的网格) |
节点属性与信号
遮挡设置
| 属性 | 类型 | 默认值 | 继承自 | 说明 |
|---|---|---|---|---|
occluder | Occluder3D | — | — | 遮挡体资源,定义遮挡的形状 |
bake_mask | int | 0xFFFFFFFF | — | 烘焙遮罩,决定遮挡体影响哪些物体 |
visible | bool | true | — | 遮挡体是否启用(继承自 Node) |
信号
| 信号 | 触发时机 | 继承自 | 说明 |
|---|---|---|---|
| 无自有信号 | — | — | OccluderInstance3D 自身不发出信号 |
常用方法
| 方法 | 返回值 | 说明 |
|---|---|---|
GetOccluder() | Occluder3D | 获取遮挡体资源 |
SetOccluder(occ) | void | 设置遮挡体资源 |
代码示例
C
using Godot;
/// <summary>
/// 为建筑物自动创建遮挡体
/// 使用简化的 Box 形状作为遮挡体
/// </summary>
public partial class BuildingOccluder : Node3D
{
[Export] private MeshInstance3D _buildingMesh;
[Export] public float ExShrinkFactor = 0.9f; // 遮挡体比模型稍小,避免穿帮
public override void _Ready()
{
if (_buildingMesh == null) return;
// 获取模型的包围盒
var aabb = _buildingMesh.GetAabb();
// 创建简化的遮挡体(比模型稍小)
var occluder = new Occluder3D();
var size = aabb.Size * ExShrinkFactor;
occluder.SetVertices(new Vector3[]
{
new(-size.X / 2, -size.Y / 2, -size.Z / 2),
new( size.X / 2, -size.Y / 2, -size.Z / 2),
new( size.X / 2, size.Y / 2, -size.Z / 2),
new(-size.X / 2, size.Y / 2, -size.Z / 2),
new(-size.X / 2, -size.Y / 2, size.Z / 2),
new( size.X / 2, -size.Y / 2, size.Z / 2),
new( size.X / 2, size.Y / 2, size.Z / 2),
new(-size.X / 2, size.Y / 2, size.Z / 2),
});
// 创建遮挡体实例
var occInstance = new OccluderInstance3D
{
Occluder = occluder,
Position = aabb.Position + aabb.Size / 2f
};
AddChild(occInstance);
}
}GDScript
## 为建筑物自动创建遮挡体
## 使用简化的 Box 形状作为遮挡体
extends Node3D
@export var building_mesh: MeshInstance3D
@export var shrink_factor: float = 0.9 # 遮挡体比模型稍小,避免穿帮
func _ready():
if building_mesh == null:
return
# 获取模型的包围盒
var aabb = building_mesh.get_aabb()
# 创建简化的遮挡体(比模型稍小)
var occluder := Occluder3D.new()
var size = aabb.size * shrink_factor
occluder.set_vertices([
Vector3(-size.x / 2, -size.y / 2, -size.z / 2),
Vector3( size.x / 2, -size.y / 2, -size.z / 2),
Vector3( size.x / 2, size.y / 2, -size.z / 2),
Vector3(-size.x / 2, size.y / 2, -size.z / 2),
Vector3(-size.x / 2, -size.y / 2, size.z / 2),
Vector3( size.x / 2, -size.y / 2, size.z / 2),
Vector3( size.x / 2, size.y / 2, size.z / 2),
Vector3(-size.x / 2, size.y / 2, size.z / 2),
])
# 创建遮挡体实例
var occ_instance := OccluderInstance3D.new()
occ_instance.occluder = occluder
occ_instance.position = aabb.position + aabb.size / 2.0
add_child(occ_instance)使用建议
- 遮挡体应该用简化的形状,不需要和模型完全一致,一个方块就够了
- 遮挡体比模型稍小一点,避免边缘出现渲染错误
- 只对大型、不透明的物体添加遮挡体(墙壁、建筑、山体)
- 小物体(椅子、花盆)不需要遮挡体,因为省不了多少渲染
- 在项目设置中开启 Occlusion Culling:Project Settings → Rendering → Occlusion Culling
