2016-11-25 14 views
0

Я пытаюсь сделать простую игру в Unity для GearVR. В игре у меня есть сцена, где пользователь может перемещаться по списку предметов. Элемент может быть выбран, если пользователь нажимает на него. Для навигационной части пользователь должен иметь возможность использовать как движение головы, так и салфетки, чтобы вращать предметы (сдвигаясь на один/минус один при каждом щелчке правой/левой руки).Unity3D: не знаю, как использовать Quaternion.Slerp(); вращение становится быстрее

Теперь проблема: я могу сделать всю эту работу с приведенным ниже кодом (установленным как компонент для родительского элемента), но вращение продолжает увеличиваться, тем больше я использую swipes. Я не могу понять, почему ... все еще работаю над этим.
Любой вид помощи оценен XD

private void ManageSwipe(VRInput.SwipeDirection sw) 
{ 
    from = transform.rotation; 
    if (sw == VRInput.SwipeDirection.LEFT) 
    { 
     to = Quaternion.Euler(new Vector3(0, from.eulerAngles.y + 30, 0));   
    } 
    if (sw == VRInput.SwipeDirection.RIGHT) 
    { 
     to = Quaternion.Euler(new Vector3(0, from.eulerAngles.y - 30, 0)); 
    } 
    StartCoroutine(Rotate()); 
} 

IEnumerator Rotate(bool v) 
{ 
    while (true) 
    { 
     transform.rotation = Quaternion.Slerp(from, to, Time.deltaTime);   
     yield return null; 
    } 
} 

Я использую Unity 5.4.1f1 и JDK 1.8.0.

PS. Не будьте тверды на меня, так как это мой первый вопрос.
Кстати ... Привет всем XD

+1

Этот код настолько ошибочен, что я даже не знаю с чего начать. Несмотря на то, что вы нашли решение, оно все еще не так. Я не думаю, что ваша функция 'Rotate' будет когда-либо существовать, потому что она имеет' while (true) 'loop. Кроме того, эта функция вызывается каждый раз, когда происходит прокрутка. В какой-то момент все будет медленно. Кроме того, если вы когда-либо проходите 0 до функции «Поворот», все ваше приложение замерзнет. Чтобы исправить это, поставим 'yield return null;' внутри цикла while не внутри оператора if в цикле while ... – Programmer

+0

Спасибо за исправление. Я думаю, вы правы в этом вопросе. Сказав это, я, как и многие другие, отправляю сюда после многих попыток и ошибок. Я нашел решение, а не решение. И я был бы вам признателен, если вы захотите, как и где это неправильно. – remmargorp

+0

Исправлено выходное значение null; из инструкции if(). Фиксированный поворот (int v) для поворота (bool v).Если удалить true, объекты будут вращаться только для фрейма, а не для адресата Lerp. Вы можете мне помочь? – remmargorp

ответ

1

исправленных большинство проблем, о которых я говорил в комментариях. Осталось все еще в цикле while. Прямо сейчас, нет способа выйти из цикла while, и это приведет к тому, что несколько экземпляров функции Rotate будут работать одновременно.

но вращение продолжает расти, тем больше я использовать пойло

Решения для хранения ссылок на одну функции сопрограммной затем остановить его, прежде чем начать новую.

Нечто подобное.

IEnumerator lastCoroutine; 
lastCoroutine = Rotate(); 
... 
StopCoroutine(lastCoroutine); 
StartCoroutine(lastCoroutine); 

Вместо while (true), вы должны иметь таймер, который существует в то время цикла. В это время функция Rotate постоянно работает. Вы должны остановить его после перехода от поворота к вращению цели.

Что-то, как это должно работать:

while (counter < duration) 
{ 
    counter += Time.deltaTime; 
    transform.rotation = Quaternion.Lerp(from, to, counter/duration); 
    yield return null; 
} 

Вот что весь ваш код должен выглядеть следующим образом:

IEnumerator lastCoroutine; 

void Start() 
{ 
    lastCoroutine = Rotate(); 
} 

private void ManageSwipe(VRInput.SwipeDirection sw) 
{ 

    //from = transform.rotation; 
    if (sw == VRInput.SwipeDirection.LEFT) 
    { 
     to = Quaternion.Euler(new Vector3(0, from.eulerAngles.y + 30, 0)); 
    } 
    if (sw == VRInput.SwipeDirection.RIGHT) 
    { 
     to = Quaternion.Euler(new Vector3(0, from.eulerAngles.y - 30, 0)); 
    } 
    //Stop old coroutine 
    StopCoroutine(lastCoroutine); 
    //Now start new Coroutine 
    StartCoroutine(lastCoroutine); 
} 

IEnumerator Rotate() 
{ 
    const float duration = 2f; //Seconds it should take to finish rotating 
    float counter = 0; 

    while (counter < duration) 
    { 
     counter += Time.deltaTime; 
     transform.rotation = Quaternion.Lerp(from, to, counter/duration); 
     yield return null; 
    } 
} 

Вы можете увеличить или уменьшить переменную duration.

+0

Угадайте, как это выглядит, когда вы получаете некоторый опыт ... Спасибо за вашу помощь! – remmargorp

+0

Добро пожаловать! – Programmer

1

Попробуйте использовать Lerp из текущего вращения не последний:

transform.rotation = Quaternion.Slerp(transform.rotation, to, Time.deltaTime); 
+0

Я пробовал это, но таким образом вращение вообще не останавливается, так как «to» - это кватернион, определяемый как поворот «трансформации». to = Quaternion.Euler (новый Vector3 (0, transform.eulerAngles.y + 30, 0)); – remmargorp

+0

Решенный! Спасибо за ваш ответ. – remmargorp