Godot 3D中如何对特定相机隐藏对象实现本地玩家身体不可见
Culling Mask完全可以实现你要的效果,核心是利用Godot渲染层与相机遮罩的匹配规则,配合多人网络的权限判断做差异化设置即可,具体方案如下:
实现原理
- Godot中所有可渲染3D/2D节点都有
layers属性,标记节点所属的渲染层,单个节点可以同时归属多个层 - 每个相机的
cull_mask属性是位掩码,只有节点所属的层在相机的cull_mask中被勾选时,节点才会被该相机渲染,未匹配的节点会直接被剔除,不进入后续渲染流程 - 我们只需要给本地客户端上属于自己的那个玩家身体分配一个独立的渲染层,让本地玩家的相机不渲染这个层,其他所有远端玩家实例的身体保持在默认渲染层,就能实现“自己看不到自己身体,其他人能正常看到”的效果。
具体操作步骤
1. 新建专属渲染层
打开编辑器顶部菜单「项目 > 项目设置」,找到「层与遮罩 > 3D层」分类,选择一个未使用的空层(比如第2层),将其命名为LocalPlayerBody方便后续维护。
2. 编写网络权限判断逻辑
在你的玩家场景根节点上挂载GDScript逻辑,在节点初始化时判断当前实例是否为本地玩家控制的实例,只有本地实例才做身体分层和相机剔除设置,远端实例保持默认配置即可。
Godot 4 参考代码:
extends CharacterBody3D # 替换成你自己的玩家根节点类型 # 绑定场景内的节点引用,匹配你描述的结构:Skeleton、Camera3D均为玩家根节点的直接子节点 @onready var player_skeleton: Skeleton = $Skeleton @onready var local_camera: Camera3D = $Camera3D # 这里填你刚才新建的专属层编号,比如用第2层就填2 const LOCAL_BODY_LAYER_INDEX := 2 func _ready(): # 只处理本地受控的玩家实例 if is_multiplayer_authority(): # 计算专属层对应的位掩码值 var local_body_mask = 1 << (LOCAL_BODY_LAYER_INDEX - 1) # 将本地玩家的骨骼身体移到专属渲染层,移出默认层 player_skeleton.layers = local_body_mask # 本地相机的剔除遮罩移除专属层,不再渲染自己的身体 local_camera.cull_mask &= ~local_body_mask # 远端玩家实例不做任何修改:骨骼留在默认渲染层,所有相机默认渲染默认层,其他玩家自然能看到
如果你使用Godot 3版本,只需要将代码里的
CharacterBody3D替换为KinematicBody、Camera3D替换为Camera、is_multiplayer_authority()替换为is_network_master()即可,核心逻辑完全一致。
常见注意点
- 不要直接在编辑器里静态把Skeleton节点的渲染层改成专属层:这样会导致所有客户端上生成的玩家实例(包括其他玩家的身体)都被移到专属层,其他玩家的相机默认不渲染这个层,就会出现所有人都看不到别人身体的问题,必须通过网络权限判断动态修改。
- 如果你需要做第一人称可见的手、武器、道具模型,把这些模型放在默认渲染层(或者单独新建第一人称专属层,保证本地相机的cull_mask包含该层即可),不会被身体的剔除规则影响。
- 这个方案的性能开销极低:被cull_mask剔除的物体不会进入相机的视锥体裁剪、绘制等后续渲染流程,比全局设置
visible = false更灵活——后者会让节点对所有相机都不可见,无法满足分相机可见的需求。
内容的提问来源于stack exchange,提问作者Adi B.
相关产品推荐
相关产品推荐

