嗨,我有一个 Unity 应用程序,它使用谷歌 Cardboard SDK 来启用立体视图,所以我将有一个支持 VR 的应用程序。我的应用程序运行良好。
但是如果我将播放器设置方向设置为自动方向,只允许横向左侧和横向右侧,则会出现问题。当它在左侧横向时,一切正常,但是当它在右侧横向时,纸板视图将转动 180 度(设置按钮移动到屏幕底部),但我的统一对象没有。因此我有一个颠倒的物体。
有什么方法可以解决这个问题?
谢谢。
嗨,我有一个 Unity 应用程序,它使用谷歌 Cardboard SDK 来启用立体视图,所以我将有一个支持 VR 的应用程序。我的应用程序运行良好。
但是如果我将播放器设置方向设置为自动方向,只允许横向左侧和横向右侧,则会出现问题。当它在左侧横向时,一切正常,但是当它在右侧横向时,纸板视图将转动 180 度(设置按钮移动到屏幕底部),但我的统一对象没有。因此我有一个颠倒的物体。
有什么方法可以解决这个问题?
谢谢。
SDK 用于读取陀螺仪的本机代码似乎仅针对横向左方向进行了硬编码。这可以通过编辑 BaseCardboardDevice.cs 并将 UpdateState() 的定义替换为以下代码来解决:
private Quaternion fixOrientation;
public override void UpdateState() {
GetHeadPose(headData, Time.smoothDeltaTime);
ExtractMatrix(ref headView, headData);
headPose.SetRightHanded(headView.inverse);
// Fix head pose based on device orientation (since native code assumes Landscape Left).
switch (Input.deviceOrientation) {
case DeviceOrientation.LandscapeLeft:
fixOrientation = Quaternion.identity;
return;
case DeviceOrientation.LandscapeRight:
fixOrientation = Quaternion.Euler(0, 0, 180);
break;
}
headPose.Set(headPose.Position, headPose.Orientation * fixOrientation);
}
我也建议在 Cardboard 设置中关闭 Neck Model Scale(将其设置为 0),因为此代码不会正确显示。
我已经解决了这个问题,这是解决方案(适用于 Cardboard v0.5.2)
首先,根据 smd 的建议,您需要在 BaseCardboardDevice / UpdateState() 中应用方向调整。但是,您应该检查 ScreenOrientation 而不是 DeviceOrientation。代码如下:
public override void UpdateState() {
ProcessEvents();
GetHeadPose(headData);
ExtractMatrix(ref headView, headData);
headPose.SetRightHanded(headView.inverse);
if (Screen.orientation == ScreenOrientation.LandscapeRight) {
headPose.Set(headPose.Position, headPose.Orientation * Quaternion.Euler(0, 0, 180)); // Workaround
}
这将修复方向,但这还不够,因为在 Cardboard Recenter() 之后您将面临错误的方向。要解决此问题,您还需要在 CardboardHead / UpdateHead() 方法中应用旋转,代码如下:
private void UpdateHead() {
if (updated) { // Only one update per frame, please.
return;
}
updated = true;
Cardboard.SDK.UpdateState();
if (trackRotation) {
var rot = Cardboard.SDK.HeadPose.Orientation;
if (Screen.orientation == ScreenOrientation.LandscapeRight) {
rot = Quaternion.Euler(0, 180, 0) * rot; // << Workaround
}
if (target == null) {
transform.localRotation = rot;
} else {
transform.rotation = target.rotation * rot;
}
}
if (trackPosition) {
Vector3 pos = Cardboard.SDK.HeadPose.Position;
if (target == null) {
transform.localPosition = pos;
} else {
transform.position = target.position + target.rotation * pos;
}
}
if (OnHeadUpdated != null) {
OnHeadUpdated(gameObject);
}
}
您可以添加:
headPose.Set(headPose.Position, headPose.Orientation * Quaternion.Euler(0,0,180));
在 BaseCardboardDevice 类的 UpdateState() 和。无论我如何打开我尝试过的设备,它都为我解决了这个问题。Unity 5 纸板 SDK v0.5.1
var fixOrientation = Quaternion.identity;
// Fix head pose based on device orientation (since native code assumes Landscape Left).
switch (Input.deviceOrientation) {
case DeviceOrientation.LandscapeLeft:
fixOrientation = Quaternion.identity;
break;
case DeviceOrientation.LandscapeRight:
fixOrientation = Quaternion.Euler(0, 0, 180);
break;
default:
Debug.Log ("Error No Orientation" + Input.deviceOrientation.ToString ());
break;
}
headPose.Set(headPose.Position, headPose.Orientation * fixOrientation);
现在,Cardboard SDK 变成了 GoogleVR,所以我在 GvrDevice.cs 上是这样写的
让您的应用程序同时出现在 LandscapeLeft 和 LandscapeRight 中的一种方法是,在 Start 方法中按以下顺序启用屏幕设置:
void Start () {
Screen.orientation = ScreenOrientation.Landscape;
Screen.orientation = ScreenOrientation.AutoRotation;
Screen.autorotateToPortrait = false;
Screen.autorotateToPortraitUpsideDown = false;
}
基本上你强制一侧,然后启用自动旋转,然后防止旋转是纵向的。
请注意,这样您的应用程序可以在两种地形上运行,因此您只需向左或向右旋转屏幕。
-
另请注意,这也适用于一个使用 Cardboard 的VR 应用程序。