主要保持 360 度旋转,同时在 VR 和普通模式之间切换



我开发了一款使用Unity和Google VR SDK的VR游戏。我也希望游戏可以在没有VR耳机的情况下玩。我应该如何实现从VR到普通模式的切换,反之亦然?我想在使用手机陀螺仪在正常模式下保持 360 度旋转。我在网上查看了许多脚本,但我找不到任何可以做到这一点的东西。

我发现切换模式可以使用XRSettings.enabled = true/false(取决于模式(来完成,但是如何在正常(非VR模式(下保持360度旋转

这是我写的脚本:

public class GyroToggleManager : MonoBehavior {

private int flag = 0;
private Quaternion offset;
IEnumerator SwitchToVR() {
string desiredDevice = "cardboard";
XRSettings.LoadDeviceByName(desiredDevice);
yield return null;
XRSettings.enabled = true;
transform.localRotation = Quaternion.identity;
}
IEnumerator SwitchTo2D() {
Input.gyro.enabled = true;
// couldn't figure out how to find this.
offset = ;
XRSettings.LoadDeviceByName("");
yield return null;
transform.localRotation = Quaternion.identity;
}
// Use this for initialization
void Start () {
if(XRSettings.enabled == false){
Input.gyro.enabled = true;
}
}
// Update is called once per frame
void Update () {
if (XRSettings.enabled) {
return;
}
//Also tried different combinations here nothing worked.
transform.localRotation = Input.gyro.attitude ;
}
public void StartVR(){
if(XRSettings.enabled == false){
StartCoroutine (SwitchToVR ());
}
}
public void StartN(){
if(XRSettings.enabled == true){
StartCoroutine(SwitchTo2D());
}
}

}

更新的脚本:

public class GyroToggleManager : MonoBehavior {

Quaternion offset;
IEnumerator SwitchToVR() {
string desiredDevice = "cardboard";
XRSettings.LoadDeviceByName(desiredDevice);
yield return null;
XRSettings.enabled = true;
transform.rotation = Quaternion.identity;
}
IEnumerator SwitchTo2D()
{
Input.gyro.enabled = true;
//Get offset.. Subtract Camera rotation from Gyro rotation
offset = transform.rotation * Quaternion.Inverse(GyroToUnity(Input.gyro.attitude));
XRSettings.LoadDeviceByName("");
yield return null;
XRSettings.enabled = false;
}
private static Quaternion GyroToUnity(Quaternion q)
{
return new Quaternion(q.x, q.y, -q.z, -q.w);
}
// Use this for initialization
void Start () {
if(XRSettings.enabled == false){
Input.gyro.enabled = true;
}
}
void Update()
{
if (XRSettings.enabled)
{
return;
}
//Add the gyro value with the offset then apply to the camera 
transform.rotation = offset * GyroToUnity(Input.gyro.attitude);
}

public void StartVR(){
if(XRSettings.enabled == false){
StartCoroutine (SwitchToVR ());
}
}
public void StartN(){
if(XRSettings.enabled == true){
StartCoroutine(SwitchTo2D());
}
}

}

下面是一个简单的摄像机跟随脚本,它跟随球员的球,同时保持摄像机和玩家之间的偏移距离。它使用偏移值来实现此目的,方法是从玩家的位置中减去摄像机的位置,然后将该偏移重新应用于摄像机的位置,并在UpdateLateUpdate函数中具有当前玩家位置。

public Transform playerTransform;
public Transform mainCameraTransform = null;
private Vector3 cameraOffset = Vector3.zero;
void Start()
{
mainCameraTransform = Camera.main.transform;
//Get camera-player Transform Offset that will be used to move the camera 
cameraOffset = mainCameraTransform.position - playerTransform.position;
}
void LateUpdate()
{
//Move the camera to the position of the playerTransform with the offset that was saved in the beginning
mainCameraTransform.position = playerTransform.position + cameraOffset;
}

上面的示例和代码并不完全是您的解决方案,但它是了解您需要做什么的最简单方法。

在您的情况下,您需要从陀螺仪传感器或Input.gyro.attitude中减去相机的旋转。微小的变化是你不能真正使用-+,因为两者都Quaternion不像上面的例子那样Vector3

  • 从另一个Quaternion减去Quaternion,就像我在Start函数与Vector3,乘以另一个的倒数Quaternion.反之亦然 用Quaternion.Inverse获得。

  • 像我在LateUpdate函数中那样添加两个Quaternions上面有Vector3,只需将两者相乘Quaternion即可。

以下是代码中的相关更改:

Quaternion offset;
IEnumerator SwitchTo2D()
{
Input.gyro.enabled = true;
//Get offset.. Subtract Camera rotation from Gyro rotation
offset = transform.rotation * Quaternion.Inverse(GyroToUnity(Input.gyro.attitude));
XRSettings.LoadDeviceByName("");
yield return null;
}
// Update is called once per frame
void Update()
{
if (XRSettings.enabled)
{
return;
}
//Add the gyro value with the offset then apply to the camera 
transform.rotation = offset * GyroToUnity(Input.gyro.attitude);
}
private static Quaternion GyroToUnity(Quaternion q)
{
return new Quaternion(q.x, q.y, -q.z, -q.w);
}

GyroToUnity函数用于在将陀螺仪坐标应用于摄像机之前将其转换为 Unity 的坐标。陀螺仪传感器使用右手坐标,而 Unity 的相机和其他对象使用左手坐标。有关详细信息,请参阅此处。

最新更新