Main поддерживает 360 вращений при переключении между VR и нормальным режимом - PullRequest
0 голосов
/ 30 апреля 2018

Я разработал VR-игру, используя Unity и Google VR SDK для Android. Я хочу, чтобы в игру можно было играть и без гарнитуры VR. Как мне осуществить переключение с VR на обычный режим и наоборот? Я хочу поддерживать вращение на 360 градусов в обычном режиме, используя телефонный гироскоп. Я просмотрел много сценариев онлайн, но не могу найти ничего, что сделало бы это возможным.

Я обнаружил, что переключение режимов может быть выполнено с использованием XRSettings.enabled = true / false (в зависимости от режима), но как поддерживать вращение на 360 градусов в обычном режиме (режим не VR)

Вот сценарий, который я написал:

открытый класс 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());
    }
}

}

1 Ответ

0 голосов
/ 30 апреля 2018

Ниже приведен простой скрипт слежения за камерой, который следует за мячом игрока, сохраняя расстояние смещения между камерой и игроком. Для этого он использует значение смещения, вычитая положение камеры из положения игрока, а затем повторно применяя это смещение к положению камеры с текущим положением игрока в функции Update или LateUpdate.

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, как в примере выше.

  • Чтобы вычесть a Quaternion из другого Quaternion, как я делал в 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 используется для преобразования гироскопа координата в координаты Unity перед его применением к камере. Датчик гироскопа использует координату для правой руки , а камера Unity и другие объекты используют координату для левой руки . См. это для получения дополнительной информации.

...