Godot 4.2中GL兼容模式下VisibleOnScreenNotifier3D的替代方案
自制3D对象屏幕可见性检测替代VisibleOnScreenNotifier3D
针对GL兼容模式下无法使用VisibleOnScreenNotifier3D的问题,这里提供两种可靠的替代方案,完全适配你的硬件环境:
方案一:基于相机视锥体的精确检测
利用相机的视锥体判断对象是否在可视范围内,支持体积检测,精度更高:
- 给需要检测的3D节点添加脚本,先声明信号:
signal screen_entered signal screen_exited - 定义变量并获取场景中的相机(根据你的场景结构调整路径):
var is_visible = false @onready var camera = get_node("/root/Main/Camera3D") - 在物理帧更新函数中检测状态变化:
func _physics_process(delta): # 用对象的全局包围盒判断,适合有体积的物体 var current_visible = camera.is_aabb_in_frustum(global_bounds) if current_visible != is_visible: is_visible = current_visible match is_visible: true: emit_signal("screen_entered") false: emit_signal("screen_exited") - 如果只需要检测单个点(比如对象中心),可以替换成:
var current_visible = camera.is_position_in_frustum(global_position)
方案二:屏幕坐标范围检测
通过世界坐标转屏幕坐标,判断是否在视口可见区域内:
- 同样先声明信号,然后获取视口和相机:
signal screen_entered signal screen_exited var is_visible = false @onready var viewport = get_viewport() @onready var camera = get_node("/root/Main/Camera3D") - 在帧更新函数中实现检测逻辑:
func _process(delta): # 把对象全局坐标转成屏幕坐标 var screen_pos = camera.unproject_position(global_position) # 获取视口可见矩形范围 var visible_rect = viewport.get_visible_rect() # 判断是否在矩形内,同时确保对象在相机前方 var forward = camera.global_transform.basis.z var to_object = global_position - camera.global_position var current_visible = visible_rect.has_point(screen_pos) && forward.dot(to_object) < 0 if current_visible != is_visible: is_visible = current_visible if is_visible: emit_signal("screen_entered") else: emit_signal("screen_exited")
额外提示
- 可以把上述逻辑封装成自定义节点(比如
CustomVisibleNotifier3D),方便在多个对象上复用。 - 两种方案都完全兼容GL兼容模式,不需要依赖Vulkan特性,适配你的Intel HD 5500硬件。
内容的提问来源于stack exchange,提问作者Fahad Shaikh
相关产品推荐
相关产品推荐

