WebXRInterface
继承: XRInterface < RefCounted < Object
使用 WebXR 的 AR/VR 接口。
描述
WebXR 是一种开放标准,允许创建在网络浏览器中运行的 VR 和 AR 应用程序。
因此,此接口仅在 Web 导出中运行时可用。
WebXR 支持范围广泛的设备,从功能强大的设备(如 Valve Index、HTC Vive、Oculus Rift 和 Quest)到功能低得多的设备(如 Google Cardboard、Oculus Go、GearVR 或普通智能手机)。
由于 WebXR 基于 JavaScript,它大量使用回调,这意味着 WebXRInterface 被迫使用信号,而其他 XR 接口将改为使用立即返回结果的函数。这使得 WebXRInterface 的初始化比其他 XR 接口要复杂得多。
以下是启动沉浸式 VR 会话所需的最少代码:
extends Node3D
var webxr_interface
var vr_supported = false
func _ready():
# 我们假设这个节点有一个按钮作为子节点。
# 该按钮供用户同意进入沉浸式 VR 模式。
$Button.pressed.connect(self._on_button_pressed)
webxr_interface = XRServer.find_interface("WebXR")
if webxr_interface:
# WebXR 使用了很多异步回调,所以我们连接各种
# 信号,以便接收它们。
webxr_interface.session_supported.connect(self._webxr_session_supported)
webxr_interface.session_started.connect(self._webxr_session_started)
webxr_interface.session_ended.connect(self._webxr_session_ended)
webxr_interface.session_failed.connect(self._webxr_session_failed)
# 这会立即返回——我们的 _webxr_session_supported() 方法
# (我们连接到上面的“session_supported”信号)将
# 在稍后的某个时间被调用,让我们知道它是否受支持。
webxr_interface.is_session_supported("immersive-vr")
func _webxr_session_supported(session_mode, supported):
if session_mode == 'immersive-vr':
vr_supported = supported
func _on_button_pressed():
if not vr_supported:
OS.alert("Your browser doesn't support VR")
return
# 我们想要一个沉浸式 VR 会话,而不是 AR('immersive-ar')或
# 简单的 3DoF 查看器('viewer')。
webxr_interface.session_mode = 'immersive-vr'
# 'bounded-floor' 是房间比例,'local-floor' 是站立或坐着
# 的体验(如果你有 3DoF 头戴设备,它会让你离地 1.6m),
# 而“local”会让你在 XROrigin 下。
# 这个列表意味着它会首先尝试请求“bounded-floor”,然后
# 回退到“local-floor”,最后是“local”,如果没有别的
# 支持的话。
webxr_interface.requested_reference_space_types = 'bounded-floor, local-floor, local'
# 为了使用“local-floor”或“bounded-floor”,我们还必须
# 将功能标记为必需或可选。通过将“手动跟踪”作为可选功能,
# 如果支持,它将被启用。
webxr_interface.required_features = 'local-floor'
webxr_interface.optional_features = 'bounded-floor, hand-tracking'
# 如果我们甚至无法请求会话,这将返回 false,
# 但是,它仍然可以在稍后的过程中异步失败,
# 因此我们只有在调用 _webxr_session_started() 或
# _webxr_session_failed() 方法时才知道它是真的成功还是失败。
if not webxr_interface.initialize():
OS.alert("Failed to initialize")
return
func _webxr_session_started():
$Button.visible = false
# 这告诉 Godot 开始渲染到头戴设备。
get_viewport().use_xr = true
# 这将是你最终获得的参考空间类型,与你在上面请求的类型不同。
# 如果你希望游戏在 “bounded-floor” 和 “local-floor”
# 中的运行方式有所不同,这将很有用。
print("Reference space type: ", webxr_interface.reference_space_type)
# 这将是成功启用的功能列表
#(不支持该属性的浏览器除外)。
print("Enabled features: ", webxr_interface.enabled_features)
func _webxr_session_ended():
$Button.visible = true
# 如果用户退出沉浸式模式,那么我们会告诉 Godot
# 再次渲染到网页。
get_viewport().use_xr = false
func _webxr_session_failed(message):
OS.alert("Failed to initialize: " + message)
有几种方法可以处理“控制器”输入:
使用 XRController3D 节点及其 XRController3D.button_pressed 和 XRController3D.button_released 信号。这是 Godot 中 XR 应用程序通常处理控制器的方式,但是,这仅适用于高级 VR 控制器,例如 Oculus Touch 或 Index 控制器。
使用 select、squeeze 和其他相关信号。这种方法适用于高级 VR 控制器和非传统输入源,例如屏幕上的轻敲、语音命令或设备本身的按钮按下。
你可以使用这两种方法来让你的游戏或应用程序支持更多或更窄的设备和输入法集,或者允许与更高级的设备进行更高级的交互。
教程
属性
方法
get_display_refresh_rate() const |
|
get_input_source_target_ray_mode(input_source_id: int) const |
|
get_input_source_tracker(input_source_id: int) const |
|
is_input_source_active(input_source_id: int) const |
|
void |
is_session_supported(session_mode: String) |
void |
set_display_refresh_rate(refresh_rate: float) |
信号
display_refresh_rate_changed() 🔗
显示器的刷新率发生改变后触发。
reference_space_reset() 🔗
发射以表明参考空间已被重置或重新配置。
何时(或是否)发射取决于用户的浏览器或设备,但可能包括用户改变了他们的游戏空间的大小(可以通过 XRInterface.get_play_area() 访问),或按下/按住一个按钮来重新定位他们的位置。
有关详细信息,请参阅 WebXR 的 XRReferenceSpace 重置事件。
select(input_source_id: int) 🔗
某个输入源完成其“主要动作”后发出。
请使用 get_input_source_tracker() 和 get_input_source_target_ray_mode() 获取关于该输入源的更多信息。
selectend(input_source_id: int) 🔗
某个输入源完成其“主要动作”时发出。
请使用 get_input_source_tracker() 和 get_input_source_target_ray_mode() 获取关于该输入源的更多信息。
selectstart(input_source_id: int) 🔗
某个输入源开始其“主要动作”时发出。
请使用 get_input_source_tracker() 和 get_input_source_target_ray_mode() 获取关于该输入源的更多信息。
session_ended() 🔗
用户结束 WebXR 会话时发出(可以使用浏览器或设备的 UI 结束会话)。
此时,你应该执行 get_viewport().use_xr = false,让 Godot 继续渲染至屏幕。
session_failed(message: String) 🔗
由 XRInterface.initialize() 在该会话启动失败时发出。
message 可能会包含 WebXR 的错误信息,如果没有可用信息则为空字符串。
session_started() 🔗
由 XRInterface.initialize() 在该会话启动成功时发出。
此时,可以安全地执行 get_viewport().use_xr = true,让 Godot 开始渲染至 XR 设备。
session_supported(session_mode: String, supported: bool) 🔗
由 is_session_supported() 触发,表示是否支持指定的 session_mode。
squeeze(input_source_id: int) 🔗
某个输入源完成其“主要紧握动作”后发出。
请使用 get_input_source_tracker() 和 get_input_source_target_ray_mode() 获取关于该输入源的更多信息。
squeezeend(input_source_id: int) 🔗
某个输入源完成其“主要紧握动作”时发出。
请使用 get_input_source_tracker() 和 get_input_source_target_ray_mode() 获取关于该输入源的更多信息。
squeezestart(input_source_id: int) 🔗
某个输入源开始其“主要紧握动作”时发出。
请使用 get_input_source_tracker() 和 get_input_source_target_ray_mode() 获取关于该输入源的更多信息。
visibility_state_changed() 🔗
当 visibility_state 已更改时触发。
枚举
enum TargetRayMode: 🔗
TargetRayMode TARGET_RAY_MODE_UNKNOWN = 0
不知道目标射线模式。
TargetRayMode TARGET_RAY_MODE_GAZE = 1
目标射线从观察者的眼睛出发,指向所观察的方向。
TargetRayMode TARGET_RAY_MODE_TRACKED_POINTER = 2
目标射线由手持指示器发射,很可能是 VR 触摸控制器。
TargetRayMode TARGET_RAY_MODE_SCREEN = 3
目标射线由触摸屏、鼠标等触觉输入设备发射。
属性说明
String get_enabled_features()
设置 WebXR 会话时通过 XRInterface.initialize() 成功启用的功能的逗号分隔列表。
这可能包括通过设置 required_features 和 optional_features 请求的功能,并且仅在发出 session_started 后可用。
注意:并非所有 web 浏览器都支持该功能,在这种情况下,它将是一个空字符串。
XRInterface.initialize() 在设置 WebXR 会话时使用的以逗号分隔的可选功能列表。
如果用户的浏览器或设备,不支持给定的任一功能,初始化将继续,但将无法使用所请求的功能。
这对已经初始化的接口没有任何影响。
可能的值见 MDN 文档中的 WebXR 的会话功能。
String get_reference_space_type()
参考空间类型(来自 requested_reference_space_types 属性中设置的请求类型列表),在设置 WebXR 会话时最终由 XRInterface.initialize() 使用。
可能的值来自 WebXR 的 XRReferenceSpaceType。 如果想要使用特定的参考空间类型,则它必须列在 required_features 或 optional_features 中。
String requested_reference_space_types 🔗
void set_requested_reference_space_types(value: String)
String get_requested_reference_space_types()
XRInterface.initialize() 在设置 WebXR 会话时使用的以逗号分隔的参考空间类型列表。
按顺序请求参考空间类型,将使用用户设备或浏览器支持的第一个。reference_space_type 属性包含最终选择的参考空间类型。
这对已经初始化的接口没有任何影响。
可能的值来自 WebXR 的 XRReferenceSpaceType。如果想要使用特定的参考空间类型,则它必须列在 required_features 或 optional_features 中。
XRInterface.initialize() 在设置 WebXR 会话时使用的以逗号分隔的所需功能列表。
如果用户的浏览器或设备不支持给定的任一功能,则初始化将失败并发出 session_failed 。
这对已经初始化的接口没有任何影响。
可能的值见 MDN 文档中的 WebXR 的会话功能。
建立 WebXR 会话时,XRInterface.initialize() 使用的会话模式。
这对已经初始化的接口没有任何影响。
可能的值来自 WebXR 的 XRSessionMode,包括:"immersive-vr" 、"immersive-ar" 和 "inline"。
String get_visibility_state()
指示用户是否可以看到 WebXR 会话的图像。
可能的值来自 WebXR 的 XRVisibilityState,包括 "hidden"、"visible" 和 "visible-blurred"。
方法说明
Array get_available_display_refresh_rates() const 🔗
返回当前 HMD 所支持的显示刷新率。网页浏览器支持该功能,并且该接口已初始化时才会返回。
float get_display_refresh_rate() const 🔗
返回当前 HMD 的显示刷新率。不是所有 HMD 和浏览器都支持。使用 set_display_refresh_rate() 前可能不会汇报精确值。
TargetRayMode get_input_source_target_ray_mode(input_source_id: int) const 🔗
返回给定的 input_source_id 的目标射线模式。
可用于帮助解析来自该输入源的输入。详见 XRInputSource.targetRayMode。
XRControllerTracker get_input_source_tracker(input_source_id: int) const 🔗
获取给定 input_source_id 的 XRControllerTracker。
在 WebXR 上下文中,输入源可以是类似 Oculus Touch 和 Index 控制器的高级 VR 控制器,甚至也可以是屏幕上的点击、语音命令或按下设备本身的按钮。当使用非传统输入源时,会将 XRPositionalTracker 的位置和方向解释为指向用户希望与之交互的对象的射线。
可以使用此方法获取有关触发以下信号之一的输入源的信息:
bool is_input_source_active(input_source_id: int) const 🔗
如果存在具有给定 input_source_id 的活动输入源,则返回 true。
void is_session_supported(session_mode: String) 🔗
检查给定的 session_mode 是否被用户的浏览器支持。
可能的值来自 WebXR 的 XRSessionMode,包括:"immersive-vr"、"immersive-ar" 和 "inline"。
此方法不返回任何东西,而是将结果发送给 session_supported 信号。
void set_display_refresh_rate(refresh_rate: float) 🔗
为当前的 HMD 设置屏幕刷新率。不是所有 HMD 和浏览器都支持。不会立即生效,发出 display_refresh_rate_changed 信号后才会生效。