Google Cardboard - 换场景时如何面对相同的方式?
Google Cardboard - how to face the same way when changing scenes?
我正在创建一个 VR 游戏,如果用户看一个按钮,场景就会改变。
问题是,如果我使用 SceneManager
加载新场景,用户面对的方向会重置,使其成为新的前进方向。例如,我有一个位于用户后面的退出按钮。如果他们看着它,一个新的场景将会加载,但是新的 "forward" 会在他们身后,导致他们必须完全转身才能让他们的 body 再次面向前方。
我在网上看到这个 post 但这是在 Unity 4 中。它谈到注释掉 Recenter()
和 device.Reset()
我在Unity 5(我正在使用的版本)中重复了这些步骤,但是没有效果。我在 Unity 5 Google Cardboard 脚本中也看不到 device.Reset()
段代码。
如何在播放模式下从当前场景加载新场景时保持朝向相同的方向?
谢谢!
Recenter()
是上一版GoogleVR SDK中classGvrViewer
的方法,是GoogleCardboard SDK的替代品.
要访问它,请使用单例实例 GvrViewer.Instance
。在 Cardboard SDK 上,可以使用 Cardboard.SDK.Recenter()
.
执行相同的任务
https://developers.google.com/vr/unity/reference/class/gvr-viewer#recenter
只需在退出时存储所有相机的位置和旋转值。将它们加载到 Start
函数中。大约一年前我做了类似的事情,并将分享脚本。只需将它附加到场景中的任何 GameObject。确保将相机放入每个插槽中。移动相机然后退出场景。下次您再次玩游戏时,它应该保持所有摄像机的位置。
如果它停止工作,请调用reset()
函数ONCE重置保存的数据,然后将其注释掉。只有当它停止工作时才应该调用它,这在我身上从未发生过。
#define USEWITHSECENE
using UnityEngine;
using System.Collections;
public class VRCAMRESTORE : MonoBehaviour
{
[System.Serializable]
class VRInfo
{
//Transform Info
[SerializeField]
public Vector3 mainCameraPos;
[SerializeField]
public Vector3 mainCameraLeftPos;
[SerializeField]
public Vector3 mainCameraRightPos;
[SerializeField]
public Vector3 reticleUnderMainCameraPos;
[SerializeField]
public Vector3 PreRenderCameraUnderStereoRenderPos;
[SerializeField]
public Vector3 PostRenderCameraUnderStereoRenderPos;
//Rotation Info
[SerializeField]
public Quaternion mainCameraRot;
[SerializeField]
public Quaternion mainCameraLeftRot;
[SerializeField]
public Quaternion mainCameraRightRot;
[SerializeField]
public Quaternion reticleUnderMainCameraRot;
[SerializeField]
public Quaternion PreRenderCameraUnderStereoRenderRot;
[SerializeField]
public Quaternion PostRenderCameraUnderStereoRenderRot;
}
public Camera mainCamera;
public Camera mainCameraLeft;
public Camera mainCameraRight;
public GameObject reticleUnderMainCamera;
public Camera PreRenderCameraUnderStereoRender;
public Camera PostRenderCameraUnderStereoRender;
private VRInfo vrInfo = null;
private Transform c1, c2, c3, c4, c5, c6;
//Use this for initialization
void Start()
{
intitTransform();
vrInfo = new VRInfo();
//check if vrInfo exist
string savedJsonValue = PlayerPrefs.GetString("vrInfo");
if (savedJsonValue == null)
{
updateCamTransform();
return;
}
//Convert back to class
vrInfo = JsonUtility.FromJson<VRInfo>(savedJsonValue);
//If Null, dont load the saved location
if (vrInfo == null)
{
updateCamTransform();
return;
}
//Load Aettings from the Savings
loadTransform();
}
public void reset()
{
PlayerPrefs.DeleteKey("vrInfo");
}
void intitTransform()
{
c1 = mainCamera.GetComponent<Transform>();
c2 = mainCameraLeft.GetComponent<Transform>();
c3 = mainCameraRight.GetComponent<Transform>();
c4 = reticleUnderMainCamera.GetComponent<Transform>();
c5 = PreRenderCameraUnderStereoRender.GetComponent<Transform>();
c6 = PostRenderCameraUnderStereoRender.GetComponent<Transform>();
}
private void loadTransform()
{
c1.position = vrInfo.mainCameraPos;
c1.rotation = vrInfo.mainCameraRot;
c2.position = vrInfo.mainCameraLeftPos;
c2.rotation = vrInfo.mainCameraLeftRot;
c3.position = vrInfo.mainCameraRightPos;
c3.rotation = vrInfo.mainCameraRightRot;
c4.position = vrInfo.reticleUnderMainCameraPos;
c4.rotation = vrInfo.reticleUnderMainCameraRot;
c5.position = vrInfo.PreRenderCameraUnderStereoRenderPos;
c5.rotation = vrInfo.PreRenderCameraUnderStereoRenderRot;
c6.position = vrInfo.PostRenderCameraUnderStereoRenderPos;
c6.rotation = vrInfo.PostRenderCameraUnderStereoRenderRot;
}
bool firstRun = true;
private void updateCamTransform()
{
//Prevents vrInfo == null from running every frame
if (firstRun)
{
firstRun = false;
if (vrInfo == null)
{
vrInfo = new VRInfo();
}
}
vrInfo.mainCameraPos = c1.position;
vrInfo.mainCameraRot = c1.rotation;
vrInfo.mainCameraLeftPos = c2.position;
vrInfo.mainCameraLeftRot = c2.rotation;
vrInfo.mainCameraRightPos = c3.position;
vrInfo.mainCameraRightRot = c3.rotation;
vrInfo.reticleUnderMainCameraPos = c4.position;
vrInfo.reticleUnderMainCameraRot = c4.rotation;
vrInfo.PreRenderCameraUnderStereoRenderPos = c5.position;
vrInfo.PreRenderCameraUnderStereoRenderRot = c5.rotation;
vrInfo.PostRenderCameraUnderStereoRenderPos = c6.position;
vrInfo.PostRenderCameraUnderStereoRenderRot = c6.rotation;
}
void saveToDrive()
{
string json = JsonUtility.ToJson(vrInfo);
PlayerPrefs.SetString("vrInfo", json);
PlayerPrefs.Save();
Debug.Log(json);
Debug.Log("Quit");
}
#if USEWITHSECENE
void Update()
{
updateCamTransform();
}
void OnDisable()
{
saveToDrive();
}
#else
//For iOS
#if UNITY_IOS
public void OnApplicationPause(bool pauseStatus)
{
if (pauseStatus)
{
//Convert to Json and Save
updateCamTransform();
saveToDrive();
}
}
#else
//For Other Devices
public void OnApplicationQuit()
{
//Convert to Json and Save
updateCamTransform();
saveToDrive();
}
#endif
#endif
}
我正在创建一个 VR 游戏,如果用户看一个按钮,场景就会改变。
问题是,如果我使用 SceneManager
加载新场景,用户面对的方向会重置,使其成为新的前进方向。例如,我有一个位于用户后面的退出按钮。如果他们看着它,一个新的场景将会加载,但是新的 "forward" 会在他们身后,导致他们必须完全转身才能让他们的 body 再次面向前方。
我在网上看到这个 post Recenter()
和 device.Reset()
我在Unity 5(我正在使用的版本)中重复了这些步骤,但是没有效果。我在 Unity 5 Google Cardboard 脚本中也看不到 device.Reset()
段代码。
如何在播放模式下从当前场景加载新场景时保持朝向相同的方向?
谢谢!
Recenter()
是上一版GoogleVR SDK中classGvrViewer
的方法,是GoogleCardboard SDK的替代品.
要访问它,请使用单例实例 GvrViewer.Instance
。在 Cardboard SDK 上,可以使用 Cardboard.SDK.Recenter()
.
https://developers.google.com/vr/unity/reference/class/gvr-viewer#recenter
只需在退出时存储所有相机的位置和旋转值。将它们加载到 Start
函数中。大约一年前我做了类似的事情,并将分享脚本。只需将它附加到场景中的任何 GameObject。确保将相机放入每个插槽中。移动相机然后退出场景。下次您再次玩游戏时,它应该保持所有摄像机的位置。
如果它停止工作,请调用reset()
函数ONCE重置保存的数据,然后将其注释掉。只有当它停止工作时才应该调用它,这在我身上从未发生过。
#define USEWITHSECENE
using UnityEngine;
using System.Collections;
public class VRCAMRESTORE : MonoBehaviour
{
[System.Serializable]
class VRInfo
{
//Transform Info
[SerializeField]
public Vector3 mainCameraPos;
[SerializeField]
public Vector3 mainCameraLeftPos;
[SerializeField]
public Vector3 mainCameraRightPos;
[SerializeField]
public Vector3 reticleUnderMainCameraPos;
[SerializeField]
public Vector3 PreRenderCameraUnderStereoRenderPos;
[SerializeField]
public Vector3 PostRenderCameraUnderStereoRenderPos;
//Rotation Info
[SerializeField]
public Quaternion mainCameraRot;
[SerializeField]
public Quaternion mainCameraLeftRot;
[SerializeField]
public Quaternion mainCameraRightRot;
[SerializeField]
public Quaternion reticleUnderMainCameraRot;
[SerializeField]
public Quaternion PreRenderCameraUnderStereoRenderRot;
[SerializeField]
public Quaternion PostRenderCameraUnderStereoRenderRot;
}
public Camera mainCamera;
public Camera mainCameraLeft;
public Camera mainCameraRight;
public GameObject reticleUnderMainCamera;
public Camera PreRenderCameraUnderStereoRender;
public Camera PostRenderCameraUnderStereoRender;
private VRInfo vrInfo = null;
private Transform c1, c2, c3, c4, c5, c6;
//Use this for initialization
void Start()
{
intitTransform();
vrInfo = new VRInfo();
//check if vrInfo exist
string savedJsonValue = PlayerPrefs.GetString("vrInfo");
if (savedJsonValue == null)
{
updateCamTransform();
return;
}
//Convert back to class
vrInfo = JsonUtility.FromJson<VRInfo>(savedJsonValue);
//If Null, dont load the saved location
if (vrInfo == null)
{
updateCamTransform();
return;
}
//Load Aettings from the Savings
loadTransform();
}
public void reset()
{
PlayerPrefs.DeleteKey("vrInfo");
}
void intitTransform()
{
c1 = mainCamera.GetComponent<Transform>();
c2 = mainCameraLeft.GetComponent<Transform>();
c3 = mainCameraRight.GetComponent<Transform>();
c4 = reticleUnderMainCamera.GetComponent<Transform>();
c5 = PreRenderCameraUnderStereoRender.GetComponent<Transform>();
c6 = PostRenderCameraUnderStereoRender.GetComponent<Transform>();
}
private void loadTransform()
{
c1.position = vrInfo.mainCameraPos;
c1.rotation = vrInfo.mainCameraRot;
c2.position = vrInfo.mainCameraLeftPos;
c2.rotation = vrInfo.mainCameraLeftRot;
c3.position = vrInfo.mainCameraRightPos;
c3.rotation = vrInfo.mainCameraRightRot;
c4.position = vrInfo.reticleUnderMainCameraPos;
c4.rotation = vrInfo.reticleUnderMainCameraRot;
c5.position = vrInfo.PreRenderCameraUnderStereoRenderPos;
c5.rotation = vrInfo.PreRenderCameraUnderStereoRenderRot;
c6.position = vrInfo.PostRenderCameraUnderStereoRenderPos;
c6.rotation = vrInfo.PostRenderCameraUnderStereoRenderRot;
}
bool firstRun = true;
private void updateCamTransform()
{
//Prevents vrInfo == null from running every frame
if (firstRun)
{
firstRun = false;
if (vrInfo == null)
{
vrInfo = new VRInfo();
}
}
vrInfo.mainCameraPos = c1.position;
vrInfo.mainCameraRot = c1.rotation;
vrInfo.mainCameraLeftPos = c2.position;
vrInfo.mainCameraLeftRot = c2.rotation;
vrInfo.mainCameraRightPos = c3.position;
vrInfo.mainCameraRightRot = c3.rotation;
vrInfo.reticleUnderMainCameraPos = c4.position;
vrInfo.reticleUnderMainCameraRot = c4.rotation;
vrInfo.PreRenderCameraUnderStereoRenderPos = c5.position;
vrInfo.PreRenderCameraUnderStereoRenderRot = c5.rotation;
vrInfo.PostRenderCameraUnderStereoRenderPos = c6.position;
vrInfo.PostRenderCameraUnderStereoRenderRot = c6.rotation;
}
void saveToDrive()
{
string json = JsonUtility.ToJson(vrInfo);
PlayerPrefs.SetString("vrInfo", json);
PlayerPrefs.Save();
Debug.Log(json);
Debug.Log("Quit");
}
#if USEWITHSECENE
void Update()
{
updateCamTransform();
}
void OnDisable()
{
saveToDrive();
}
#else
//For iOS
#if UNITY_IOS
public void OnApplicationPause(bool pauseStatus)
{
if (pauseStatus)
{
//Convert to Json and Save
updateCamTransform();
saveToDrive();
}
}
#else
//For Other Devices
public void OnApplicationQuit()
{
//Convert to Json and Save
updateCamTransform();
saveToDrive();
}
#endif
#endif
}