【问题标题】:Main maintain 360 rotation while toggling between VR and Normal mode在 VR 和普通模式之间切换时,主要保持 360 度旋转
【发布时间】:2018-10-10 07:35:25
【问题描述】:

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

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

这是我写的脚本:

公共类 GyroToggleManager : MonoBehaviour {

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());
    }
}

}

更新脚本:

公共类 GyroToggleManager : MonoBehaviour {

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());
    }
}

}

【问题讨论】:

  • 我更改了标题,因为它使您的问题重复,而不是真正的问题。对于您的问题,请在切换模式之前进行旋转。切换模式后,将相机旋转设置为之前的旋转。
  • @Programmer 感谢标题更改。但是,即使我在切换到正常模式之前获得了旋转,只要 XRSettings.enabled 设置为 false,360 度移动就会停止。如何保持这种 360 度旋转?
  • 我可能误会了你。从 VR 切换到普通模式时,您希望相机保持相同的旋转吗?面对与切换之前相同的方式?如果是,请查看我的第一条评论
  • @Programmer 是的,我希望相机保持相同的旋转,但与此同时,我想在正常模式下使用移动陀螺仪保持头部跟踪。
  • 我错过了陀螺仪部分。在切换之前,获取相机位置并减去当前陀螺仪值。该值是偏移量。每一帧,(Update 函数)获取陀螺仪值并将其应用到具有该偏移量的相机上。试试这个。如果您遇到问题,请发布您的尝试代码,包括切换代码,如果可能,我会提供修复。

标签: c# unity3d google-vr game-development google-vr-sdk


【解决方案1】:

下面是一个简单的相机跟随脚本,它跟随球员的球,同时保持相机和球员之间的偏移距离。它使用一个偏移值来做到这一点,方法是从玩家的位置减去相机的位置,然后在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,如上例所示。

  • 像我在 Start 函数与 Vector3,相乘另一个 Quaternion。逆是 通过Quaternion.Inverse获得。

  • 添加两个 Quaternions,就像我在 LateUpdate 函数中所做的那样 以上与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 函数用于将陀螺仪coordinate 转换为 Unity 的坐标,然后再将其应用于相机。陀螺仪传感器使用 右手 坐标,而 Unity 的相机和其他对象使用 左手 坐标。请参阅this 了解更多信息。

【讨论】:

  • 我理解偏移的概念 :) 但是当我将更新后的脚本附加到主摄像机时,将模式更改为正常时,360 度旋转会冻结。
  • 你应该在正常模式下将XRSettings.enabled设置为false,这样Update函数中的代码才能执行。你从来没有这样做过,所以if (XRSettings.enabled) { return; } 是真的并且从那个函数返回。在 SwitchTo2D 函数的末尾执行此操作。
  • 您可以在您的问题中添加 EDIT,然后在其下添加新脚本吗?不要删除旧脚本。只需在其下添加新的。我想看看你现在有什么。如果您在编辑器或设备上运行它,还要提及。
  • 编辑了问题。我在 Android 设备上运行它。
  • 我现在没有要测试的设备,代码看起来不错。将Debug.Log(XRSettings.enabled) 放入Update 函数中,看看它是否完全变为false。 This 是如何看到Debug.Log 登录android。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-08
  • 2013-10-25
  • 1970-01-01
相关资源
最近更新 更多