Что на самом деле движется в бесконечном бегуне?
Например, знаменитая игра Flappy Bird или что-то подобное, игрок (в данном случае птица или камера в зависимости от того, что вы предпочитаете) двигаетесь вперед или весь мир движется назад (птица меняет положение Y и имеет постоянную позицию X)?
4 ответа
Оба варианта работают.
Но если вы хотите, чтобы бесконечный бегун был поистине бесконечным, вам нужно будет держать игрока неподвижным и перемещать мир. В противном случае вы в конечном итоге попадете в пределы переменных, которые вы используете для хранения X-позиции. Целое число будет в конечном счете переполняться, и переменная с плавающей запятой станет все более менее точной, что заставляет геймплей сглаживать через некоторое время. Но вы можете избежать этой проблемы, используя достаточно большой тип, который никто не столкнется с этими проблемами в течение времени, которое можно было бы играть за один сеанс (когда игрок перемещается 1000 пикселей в секунду, 32-битное целое будет переполняться через 49 дней).
Так что делайте то, что кажется вам концептуально более интуитивным.
Я немного не согласен с ответом Филиппа ; или, по крайней мере, с тем, как он это представил. Создается впечатление, что перемещение мира вокруг игрока может быть лучшей идеей; когда это полная противоположность. Итак, вот мой собственный ответ ...
Обе опции могут работать, но, как правило, это плохая идея «инвертировать физику», перемещая мир вокруг игрока, а не игрока по всему миру.
Потери производительности /отходы:
В мире обычно будет много статических или спящих объектов. У игрока будет одно или несколько объектов. Перемещение всего мира вокруг игрока означает перемещение всего на сцене, кроме игрока. Статические объекты, спящие динамические объекты, активные динамические объекты, источники света, звуковые источники и т. Д .; все должны быть перемещены.
Это (очевидно) значительно дороже, чем перемещение только того, что на самом деле движется (игрок и, возможно, еще несколько вещей).
Поддержание работоспособности и amp; Расширяемость:
Перемещение мира вокруг игрока заставляет мир (и все в нем) быть тем местом, где вещи наиболее активно происходят. Любая ошибка или изменение в системе означает, что, возможно, все меняется. Это не лучший способ сделать что-то; вы хотите, чтобы ошибки /изменения были как можно более изолированными, так что вы не получаете неожиданного поведения где-то, где вы не вносили изменений.
Есть также много других проблем с этим подходом. Например, это ломает многие предположения о том, как все должно работать внутри двигателя. Например, вы не сможете использовать динамический RigidBody
для чего-либо, кроме игрока; поскольку объект с прикрепленным кодом RigidBody
, не установленным в кинематику, будет действовать неожиданно при настройке положения /вращения /масштабирования (который вы будете делать каждый кадр для каждого объекта в сцене, кроме игрока
Создав ответ XenoRo , вместо описанного метода повторного укоренения, можно было бы сделать следующее
Создайте круговой буфер частей вашей бесконечной карты, сгенерированной вашим персонажем, с позицией, обновленной с помощью арифметики по модулю (так что вы просто запускаете круглый буфер). Начните заменять части своего буфера, как только ваш персонаж покинет кусок. У игроков, обновляющих уравнение, будет что-то вроде:
player.position = (player.position + player.velocity) % worldBuffer.width;
вот пикторальный пример того, о чем я говорю:
merzenne twister , это не большая проблема, так как использует 2.5k внутреннее состояние, но если вы используете крошечный вариант, у вас есть 2 ^ 127-1 max итераций перед повторением (или хуже), это все еще астрономически большое число, однако . Вы можете исправить проблемы повторяющегося периода, даже если ваш PRNG имеет короткий период через
Как уже было сказано и принято, это действительно зависит от объема и стиля вашей игры, но поскольку он не упоминался: FlappyBird перемещает препятствие по экрану, а не по всему миру.
Создатель создает объекты вне экрана с фиксированной скоростью в направлении Vector2.left
.