StartCoroutine с IEnumerator, включая Time.deltaTime, иногда бесконечные циклы

Я надеюсь, что кто-нибудь поможет мне с проблемой, с которой я столкнулся при создании моей 2D-игры. Я использую Unity для создания приложения для Android. Я перемещаю своего персонажа (козла) по экрану с помощью системы сеток (GridMove - http://wiki.unity3d.com/index.php/GridMove).

Я включил скрипт Global и Move по следующим ссылкам:

Глобальный: http://codeshare.io/i6BDn

Переместить: http://codeshare.io/JHDAs

В функции обновления перемещения есть StartCoroutine, которая перемещает козу в определенное положение (на основе размера сетки, равного 0,5).

Для transform.position задаются значения Vector3.Lerp и Time.deltaTime. На моем компьютере он работает нормально, но когда я начинаю открывать программы или подключаю отладчик, козел, кажется, продолжает зацикливаться в той же позиции. Это также происходит на телефоне низкого уровня или даже на Samsung Galaxy s4.

Есть ли способ остановить козу от сброса его transform.position или как это проверить? Кажется, я не могу точно определить, где что-то идет не так.

введите здесь описание изображения

Положение козла зацикливания:  введите описание изображения здесь

Если вам нужна дополнительная информация, просто дайте мне знать.


person Tim Ververs    schedule 21.09.2015    source источник
comment
Пожалуйста, укажите в вопросе ваш реальный код, а не ссылку для совместного использования кода.   -  person MX D    schedule 21.09.2015
comment
Вам действительно нужен доход return 0; в методе переезда?   -  person Volodymyr Baydalka    schedule 21.09.2015


Ответы (1)


while (t <= 1f)

Давайте подумаем об этом на секунду. Вы хотите переместить его из позиции 0f в позицию 1f. Если он достигнет 1f, код не перестанет выполняться, потому что условие position == 1f по-прежнему удовлетворяет условию цикла while.

вместо этого должно быть так:

float threshold = Single.Epsilon;
while ((1f - t) > threshold)

Большая проблема:

//Done with moving, set bool to false to "release" the update function
t = 0;
isMoving = false;
yield return 0;

Не заканчивайте свой Ienumerator yield return 0. Он делает то же самое, что и yield return null, и снова зацикливает IEnumerator. Вы также просто сбрасываете свои переменные, чтобы все началось с позиции 0f. Вместо этого вы должны закончить IEnumerator, просто завершив код. Он не будет повторяться снова:

//Done with moving, set bool to false to "release" the update function
t = 0;
isMoving = false;
person maksymiuk    schedule 21.09.2015
comment
Собираюсь попробовать это, спасибо. Я также сообщу о своих выводах и отметлю их, если они решены. - person Tim Ververs; 21.09.2015
comment
Извините .. Проблема продолжает возникать даже с предложенными вами изменениями. Вот новый файл Move: codehare.io/5kem6 - person Tim Ververs; 22.09.2015
comment
хм, похоже, это должно сработать, но есть пара вещей, которые я бы изменил. Прежде всего, я бы включил тот факт, что движение происходит в блоке if для StartCoroutine как такового: if (tempPauseTime <= 0 && !isMoving) таким образом, даже если пауза закончилась, он все равно будет ждать завершения всего движения, прежде чем запускать его снова. - person maksymiuk; 22.09.2015
comment
Другое дело, что вы не должны прибавлять или вычитать константу каждый кадр. Это связано с тем, что кадры рендеринга не выполняются с точными интервалами, поэтому изменение значения на константу, подобную этой, каждый кадр tempPauseTime -= 0.01f; будет очень прерывистым. Вместо этого должно получиться так: tempPauseTime -= Time.deltaTime * decreaseSpeed; - person maksymiuk; 22.09.2015
comment
Вы можете предоставить точный код? Или я все правильно делаю? tempPauseTime -= (Time.deltaTime * 0.01f); с if (tempPauseTime <= 0 && !isMoving), затем StartCoroutine(move(transform)); и tempPauseTime = pauseTime; - person Tim Ververs; 23.09.2015
comment
да, мне это кажется нормальным, хотя ваша скорость таймера 0.01f кажется немного низкой, deltaTime дает вам количество в секундах, которое потребовалось кадру для рендеринга из последнего кадра, поэтому, если вы работаете со скоростью 30 кадров в секунду, deltaTime должно усредняться примерно на 0.033f, и если вы умножите это на вашу скорость, 0.01f, тогда вы будете усреднять, вычитая 0.00033f из вашего таймера каждый кадр. Я бы предложил использовать общедоступную переменную для вашей скорости, которую вы можете регулировать во время выполнения, пока не получите наилучшие результаты. - person maksymiuk; 23.09.2015
comment
Спасибо! Я меняю 0.01f на 0.3f, и, похоже, все работает нормально. К сожалению, на мобильном устройстве эта ошибка продолжает происходить ... Я не могу понять проблему, но кажется, что медленные устройства (иногда и мой компьютер) позволяют персонажу бесконечно зацикливаться на одном и том же месте. - person Tim Ververs; 23.09.2015