2017-01-29 14 views
1

Я использую Unity, чтобы создать игру, в которой используется гироскоп. Я пытаюсь обнаружить вращение устройства вокруг оси, проходящей через экран, я предполагаю, что это ось Z в Unity Space. Я попытался использовать Input.gyro.attitude.eulerAngles.z, но он не остается постоянным при наклоне устройства вокруг других осей, я хочу, чтобы он оставался постоянным, так что только «ось Z» определяет вращение рулевого колеса автомобиля, например. Как я могу это реализовать?Unity - гироскоп - вращение вокруг одной оси

EDIT: Я попытался сделать что-то еще. Я использовал Input.gyro.rotationRateUnbiased вместо Input.gyro.attitude.eulerAngles

Вот код:

Vector3 gInput = Input.gyro.rotationRateUnbiased; 
    gyroEuler += gInput * Time.deltaTime * Mathf.Rad2Deg; 

    float rollAngle = gyroEuler.z; 

    while (rollAngle < 0) 
    { 
     rollAngle += 360; 
    } 
    while (rollAngle > 360) 
    { 
     rollAngle -= 360; 
    } 

Но gyroEuler будет установлен (0, 0, 0) независимо от ориентации устройства в начале игры, так что ориентация устройства не будет известна в начале а также Input.gyro.rotationRateUnbiased очень неточно. Я хочу повернуть экран так, как многие игры, например, Temple Run 2, но я хочу, чтобы он мог поворачивать его на 360 градусов и получить этот угол поворота.

+0

Возможный дубликат [Как заблокировать вращение в г моей камеры во время вращения камеры с помощью мобильного ввода гироскоп] (http://stackoverflow.com/questions/41818719/how -to-lock-rotation-in-z-of-my-camera-while-rotating-the-camera-by-using-mobile) – Kardux

+0

Нет, это меня не очень помогло. –

+0

Например, вам не нужно оценивать «угол Эйлера», но вы можете просто оценить угол между преобразованной осью (по текущему вращению) и, например, землей. https://upload.wikimedia.org/wikipedia/en/thumb/3/30/Plane_with_ENU_embedded_axes.svg/220px-Plane_with_ENU_embedded_axes.svg.png – minorlogic

ответ

2

Ну, я просто попытался его, и он хорошо работает:

private void Start() 
{ 
    Input.gyro.enabled = true; 
} 

private void Update() 
{ 
    Vector3 previousEulerAngles = transform.eulerAngles; 
    Vector3 gyroInput = -Input.gyro.rotationRateUnbiased; 

    Vector3 targetEulerAngles = previousEulerAngles + gyroInput * Time.deltaTime * Mathf.Rad2Deg; 
    targetEulerAngles.x = 0.0f; // Only this line has been added 
    targetEulerAngles.z = 0.0f; 

    transform.eulerAngles = targetEulerAngles; 

    //You should also be able do it in one line if you want: 
    //transform.eulerAngles = new Vector3(0.0f, transform.eulerAngles.y - Input.gyro.rotationRateUnbiased.y * Time.deltaTime * Mathf.Rad2Deg, 0.0f); 
} 

Что вам нужно сделать, это создать центральный Transform (или использовать плеер) и родитель ваш камеры, как ребенок от него. Затем установите Камера z-расстояние, высота и угол для настройки вашего вида. Наконец, прикрепите приведенный выше сценарий к центральному Трансформация: вращение сделает вашу Камера перемещается по дуге.

EDIT: Если вы хотите использовать Input.gyro.attitude вместо этого вы можете сделать это, как следовать

private Vector3 startEulerAngles; 
private Vector3 startGyroAttitudeToEuler; 

private void Start() 
{ 
    Input.gyro.enabled = true; 
    startEulerAngles = transform.eulerAngles; 
    startGyroAttitudeToEuler = Input.gyro.attitude.eulerAngles; 
} 

private void Update() 
{ 
    Vector3 deltaEulerAngles = Input.gyro.attitude.eulerAngles - startGyroAttitudeToEuler; 
    deltaEulerAngles.x = 0.0f; 
    deltaEulerAngles.z = 0.0f; 

    transform.eulerAngles = startEulerAngles - deltaEulerAngles; 
} 

public void ResetGyro() 
{ 
    startGyroAttitudeToEuler = Input.gyro.attitude.eulerAngles; 
} 

EDIT 2:

Я предполагаю, что вы ищете будет что-то вроде this: вы можете проверить upVec.y и upVec.x для вашей оси Вниз/Вверх и Влево/Вправо.

Сначала создайте пустой GameObject, который будет использоваться как манекен, содержащий вращение гироскопа, и установите его в поле сценария phoneDummy.

public Transform phoneDummy; 

private void Start() 
{ 
    Input.gyro.enabled = true; 
} 

private void Update() 
{ 
    Vector3 gyroEuler = Input.gyro.attitude.eulerAngles; 
    phoneDummy.transform.eulerAngles = new Vector3(-1.0f * gyroEuler.x, -1.0f * gyroEuler.y, gyroEuler.z); 

    Vector3 upVec = phoneDummy.transform.InverseTransformDirection(-1f * Vector3.forward); 
} 

upVec.y будет ваш шаг и upVec.x будет вашим рулет оси. (проверьте here для оси отсчета)

Но имейте в виду ценностей из Input.gyro далеко от совершенства: вы можете использовать Input.compass.magneticHeading, если вы ищете более постоянного значения (но, конечно, менее точен один).

Надеюсь, что это помогает,

+0

Хорошо, что он отлично работает, но он не вычисляет угол точно. Я хочу, чтобы он измерил угол поворота экрана, поэтому я думал об использовании Input.gyro.attitude, но я не знаю, как его использовать, я не совсем понимаю, как это работает. –

+0

@MoazAshraf Отредактировано мое сообщение с использованием 'Input.gyro.attitude', но вы получите некоторые побочные эффекты от его использования (при изменении ориентации на 180 ° при наклоне устройства назад и вперед вокруг его вертикального положения). – Kardux

+1

Ну, это именно то, что я имел в виду, когда я сказал, что хочу, чтобы ротация была постоянной. Как я могу удалить побочный эффект, должен был быть мой вопрос. –