如何在Unity中以编程方式为部署到Android设备的应用程序设置立体声显示?
我想要一个用户可以在“VR模式”和正常模式之间切换的UI菜单。我不希望默认使用VR模式,因为它应该是运行时的选项。我知道在构建设置中有一个“支持虚拟现实”的设置,但是再次强调,我不想默认启用此功能。
如何在Unity中以编程方式为部署到Android设备的应用程序设置立体声显示?
我想要一个用户可以在“VR模式”和正常模式之间切换的UI菜单。我不希望默认使用VR模式,因为它应该是运行时的选项。我知道在构建设置中有一个“支持虚拟现实”的设置,但是再次强调,我不想默认启用此功能。
在顶部加上using UnityEngine.XR;
。
在启动函数中使用空字符串调用XRSettings.LoadDeviceByName("")
,然后再接着使用XRSettings.enabled = false;
来禁用VR以关闭VR。
如果您想稍后启用它,请调用 VR 名称并在其后跟 XRSettings.LoadDeviceByName("daydream")
,然后再接着使用XRSettings.enabled = true;
。
在每个函数调用之间应该等待一个帧。这需要使用coroutine功能完成。
此外,在某些 VR 设备上,您必须进入编辑器->项目设置->玩家,确保支持虚拟现实选框为已选中(true),然后才能使此功能正常工作。然后可以在启动函数中禁用它,并在需要时启用它。
编辑:
这在某些 VR 设备上可行,但不是所有 VR 设备都适用。尽管如此,它应该可以在 Daydream VR 上工作。完整代码示例:
IEnumerator LoadDevice(string newDevice, bool enable)
{
XRSettings.LoadDeviceByName(newDevice);
yield return null;
XRSettings.enabled = enable;
}
void EnableVR()
{
StartCoroutine(LoadDevice("daydream", true));
}
void DisableVR()
{
StartCoroutine(LoadDevice("", false));
}
调用EnableVR()
来启用VR,调用DisableVR()
来禁用VR。如果您使用的是Daydream之外的任何其他VR设备,请将该VR设备的名称传递给EnableVR()
函数中的LoadDevice
函数。
对于较新版本的Unity(例如2019.4.0f1),您可以使用XR插件管理软件包。
要启用,请调用:
XRGeneralSettings.Instance.Manager.InitializeLoader();
禁用呼叫:
XRGeneralSettings.Instance.Manager.DeinitializeLoader();
XRGeneralSettings.Instance.Manager.StartSubsystems();
停止:
XRGeneralSettings.Instance.Manager.StopSubsystems();
完整文档请参见:
https://docs.unity3d.com/Packages/com.unity.xr.management@4.0/manual/EndUser.html
2020.3.14f1
对我来说不起作用,当我运行我的Android应用程序时,我会收到这个错误。
在没有初始化管理器的情况下调用DeinitializeLoader。请确保在调用此API之前等待初始化完成。
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)]
static void TryToDeinitializeOculusLoader()
{
XRGeneralSettings.Instance.Manager.DeinitializeLoader();
}
Application.Quit
,因为设备不是Oculus头戴式显示器。
等待XRGeneralSettings.Instance.Manager.isInitializationComplete
太长时间了。
尝试了所有的RuntimeInitializeLoadType
注释。
OculusLoader.cs
#elif (UNITY_ANDROID && !UNITY_EDITOR)
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)]
static void RuntimeLoadOVRPlugin()
{
var supported = IsDeviceSupported();
if (supported == DeviceSupportedResult.ExitApplication)
{
Debug.LogError("\n\nExiting application:\n\nThis .apk was built with the Oculus XR Plugin loader enabled, but is attempting to run on a non-Oculus device.\nTo build for general Android devices, please disable the Oculus XR Plugin before building the Android player.\n\n\n");
Application.Quit();
}
if (supported != DeviceSupportedResult.Supported)
return;
try
{
if (!NativeMethods.LoadOVRPlugin(""))
Debug.LogError("Failed to load libOVRPlugin.so");
}
catch
{
// handle Android standalone build with Oculus XR Plugin installed but disabled in loader list.
}
}
#endif
解决方案
让我的构建类扩展IPreprocessBuildWithReport接口
public void OnPreprocessBuild(BuildReport report)
{
DisableXRLoaders(report);
}
///https://docs.unity3d.com/Packages/com.unity.xr.management@3.2/manual/EndUser.html
/// Do this as a setup step before you start a build, because the first thing that XR Plug-in Manager does at build time
/// is to serialize the loader list to the build target.
void DisableXRLoaders(BuildReport report)
{
XRGeneralSettingsPerBuildTarget buildTargetSettings;
EditorBuildSettings.TryGetConfigObject(XRGeneralSettings.k_SettingsKey, out buildTargetSettings);
if (buildTargetSettings == null)
{
return;
}
XRGeneralSettings settings = buildTargetSettings.SettingsForBuildTarget(report.summary.platformGroup);
if (settings == null)
{
return;
}
XRManagerSettings loaderManager = settings.AssignedSettings;
if (loaderManager == null)
{
return;
}
var loaders = loaderManager.activeLoaders;
// If there are no loaders present in the current manager instance, then the settings will not be included in the current build.
if (loaders.Count == 0)
{
return;
}
var loadersForRemoval = new List<XRLoader>();
loadersForRemoval.AddRange(loaders);
foreach (var loader in loadersForRemoval)
{
loaderManager.TryRemoveLoader(loader);
}
}
public void Awake() {
StartCoroutine(SwitchToVR(()=>{
Debug.Log("Switched to VR Mode");
}));
//For disable VR Mode
XRSettings.enabled = false;
}
IEnumerator SwitchToVR(Action callback) {
// Device names are lowercase, as returned by `XRSettings.supportedDevices`.
// Google original, makes you specify
// string desiredDevice = "daydream"; // Or "cardboard".
// XRSettings.LoadDeviceByName(desiredDevice);
// this is slightly better;
string[] Devices = new string[] { "daydream", "cardboard" };
XRSettings.LoadDeviceByName(Devices);
// Must wait one frame after calling `XRSettings.LoadDeviceByName()`.
yield return null;
// Now it's ok to enable VR mode.
XRSettings.enabled = true;
callback.Invoke();
}