Pull to refresh

Comments 22

Вот, кстати, 5-й этап самый злой. Знаю по себе. Стоит только начать оптимизировать и добрасывать функционал, который рождается в процессе работы над проектом и все — приехали. Релиза нет, но есть куча реализованных плюшек, а в голове уже готова прорва новых идей. И отказаться от этого соблазна — очень тяжело. Я не про гейм.дев, а в общем. Поэтому ТЗ на проект должно быть строгим и с конкретными целями, без размытых описаний тех или иных составляющих будущего продукта.

Ну а в целом, спасибо за пост. Продолжайте в том же духе и удаче в игрострое =)
Спасибо. Действительно, 5-й этап актуален не только для геймдева. Как вы подметили, важно всегда четко следовать ТЗ, а также уметь вовремя останавливаться.
Почему внутри метода
void changeDirection() {
      if (isMovingRight) {
         isMovingRight = false;
      } else {
         isMovingRight = true;
      }
}

пять строчек вместо одной:
void changeDirection() {
      isMovingRight = !isMovingRight;
}


InvokeRepeating ("SpawnPlatform", 1f, 0.2f);

Странное решение. Разве Вас не смущает то, что платформы будут генериться вне зависимости от положения игрока? Много опасных «а вдруг» при дальнейшей разработке проекта:
  • а вдруг игрок пройдёт первые десять платформ быстрее, чем за секунду
  • а вдруг игрок будет стоять на месте, а платформы всё генерятся и генерятся
  • а вдруг скорость игрока будет больше одной платформы за 0.2 секунды


Я понимаю, что целью статьи было немного другое, но с такими вещами аккуратнее надо быть в статьях, которые мотивируют/обучают начинающих разработчиков :)
Ваши утверждения логичны и понятны, но только не для начинающих разработчиков, которые только знакомятся с C# и геймдевом в целом. Как и было сказано, финальный код игры реализован на более глубоких познаниях языка, в нём предусмотрен и Object Pool, и прекращение генерации платформ в случае схода игрока с намеченного маршрута. В рамках данной статьи я попытался рассказать, как простыми методами и в короткий срок, можно добиться результата в Unity. Отсюда и разъяснение, что называется «на пальцах». Вам большая благодарность за уделенное внимание.
Думаю, Ваша статья совместно с нашими комментариями, дадут начинающему разработчику понятие того, что нужно учиться делать правильно. И при этом не отпугнут его от увлекательной стези геймдева, а это главное.
а вдруг игрок пройдёт первые десять платформ быстрее, чем за секунду

а с какой стати это так может случиться?

а вдруг игрок будет стоять на месте, а платформы всё генерятся и генерятся

также как и в первом вопросе. в скрипте написан явный код движения объекта. с чего это вдруг он не будет двигаться?

а вдруг скорость игрока будет больше одной платформы за 0.2 секунды

с какой стати скорость игрока будет больще 0.2 если явно указана эта скорость?
Не нужно быть прямолинейным, думаю Kos-Boss имел в виду тот случай, если разработчик надумает развивать игру, добавить возможность замедления времени, сделать паузу, сделать разные типы шариков с разной скоростью.

При таких манипуляциях придется полностью перелопачивать весь код. Вспоминать, где ты там скорость захардкодил и другие неприятные вещи.

Как сказал автор статьи, да, не стоит нагружать начинающих сразу же огромным объемом информации, что Kos-Boss и решил прокомментировать, добавив свое мнение, и это здорово. Начинающий разработчик прочитает статью, посмотрит комментарий и сделает вывод, мол: «понятно, можно написать как в статье, а можно сделать все более гибким, что позволит мне в дальнейшем с легкостью внедрять изменения».

От себя хотелось бы добавить:
void Update() {
      rb.velocity = new Vector3 (speed, 0f,0f);
   }

Значение speed стоит умножать на Time.deltaTime, чтобы предотвратить разную скорость при разном количестве fps. К примеру, если один человек запустит игру и у него будет 60 fps, а у другого компьютер более слабый, будет допустим 30 fps, то у второго человека машина будет перемещаться в два раза медленнее, по сравнению с первым, потому что у перого машина 60 раз в секунду получает ускорение speed, а у второго игрока только 30 раз в секунду, что в два раза медленнее.

Все дело в том, что функция Update() выполняется каждый кадр. Умножение любой скоростной переменной на Time.deltaTime позволит сделать её независимой от количества кадров в секунду.

Time.deltaTime изменяется в зависимости от fps, например если у человека 60 fps, Time.deltaTime образно говоря будет равен 0.25f, а если у человека игра подвисает и идет в 30 fps, то Time.deltaTime будет равен 0.5f (в два раза больше), таким образом у первого игрока 5f * 0.25f (будет выполняться 60 раз в секунду), а у второго 5f * 0.5f (будет выполняться 30 раз в секунду). В результате за реальную секунду у обоих игроков машина сдвинется на абсолютно одинаковое расстояние.

Time.deltaTime нужно применять в функциях Update() везде, где есть какие-либо переменные, отвечающие за скорость передвижения того или иного объекта.

P.S. — Нужно будет только увеличить значение speed, иначе после добавления Time.deltaTime скорость машины будет очень медленной.
Спасибо, именно это я и имел ввиду, когда писал:
Много опасных «а вдруг» при дальнейшей разработке проекта


По поводу
void Update() {
    rb.velocity = new Vector3 (speed, 0f,0f);
}

Тут в каждом кадре устанавливается скорость движения rigidbody, а не выполняется перемещение объекта на определённую величину. То есть от фпс тут будет зависеть то, как часто будет устанавливаться скорость (как часто вызывается Update()), но никак не скорость передвижения объекта. Поэтому умножать на Time.deltaTime в данном случае не нужно.

Но Вы правильно сделали, что упомянули и разъяснили принцип работы Time.deltaTime, ведь это, наверное, самая распространённая ошибка начинающего Unity-разработчика.
Спасибо про Time.deltaTime, действительно не придал значение тому, что задается velocity, а не MovePosition или AddForce какой :)
Тут стоит упомянуть начинающим разработчикам, что
1) velocity лучше руками не трогать вообще, т.к. это ломает физику объекта. Используйте .AddForce(x, y, z, ForceMode.Force);
2) все вычисления физики надо делать в FixedUpdate(), а не Update(). Он для того и предназначен, что не зависит от мощности железа игрока.
1) velocity лучше руками не трогать вообще, т.к. это ломает физику объекта. Используйте .AddForce(x, y, z, ForceMode.Force);

Тут зависит от того, с какой целью Вы хотите её менять и какая степень реализма физики Вам необходима. Если реализм важен (настолько, насколько его может обеспечить физика Unity), то использовать мгновенное изменение вектора скорости конечно же не нужно.

2) все вычисления физики надо делать в FixedUpdate(), а не Update(). Он для того и предназначен, что не зависит от мощности железа игрока.

Да, тут согласен с Вами.

Ещё из коварного вспомнилось, что для произвольного перемещения/вращения rigidibody необходимо использовать методы MovePosition/MoveRotation (или параметры position/rotation) самого rigidbody, а не трансформа.
А можно еще короче, чтобы не писать 2 раза название переменной. Хотя ваш вариант скорее более читабелен.
void changeDirection() {
      isMovingRight ^= true;
}
Вы могли бы подробнее рассказать, на какие этапы сколько времени ушло?
На первые два этапа (концепция и создание наброска) я потратил около 5 часов. Это время я провел за изучением приложений, а также за оценкой собственных возможностей. Сам процесс написания кода, начиная от простенькой поделки до более-менее приемлемой игры, отнял у меня 36 часов работы. В это время я занимался игрой с самого утра до поздней ночи, делая небольшие перерывы на прием пищи и кофе-брейки. Остальное время ушло на создание моделей, текстур и визуальной составляющей игры (еще 36 часов). Чуть более 12 часов ушли на доводку — поиски оптимального значения скорости, механика «инкама» и прочее, и еще несколько часов на создание иконки и баннеров, необходимых для публикации в плеймаркет. Если считать по дням, то разработку я начал вечером 8 марта, а уже 14-го, приложение было опубликовано.
UFO just landed and posted this here
Если вы про графическое оформление GUI — то этот этап я оставляю практический на самый конец. А так, GUI присутствует в игре с самого начала и наращивается по мере развития игры (используются стандартные компоненты Unity).
UFO just landed and posted this here
Если интересно, у нас это обычно делается следующим образом. Программист пишет логику самой игры, по ходу дела привязывая к ней необходимые элементы пользовательского интерфейса (на заглушках). Затем человек, ответственный за GUI, вместо заглушек подставляет необходимые графические элементы. Если необходимы какие-то дополнительные эффекты, для которых необходимо доработать логику, то за дело опять берётся программист.

Возможно, это не самый лучший подход и, в случае больших проектов в больших компаниях, всё необходимо планировать заранее. Но для маленькой студии с постоянной внутренней обратной связью это хороший и вполне достаточный вариант :)
Большое спасибо за туториал! Респект!
Я могу ошибаться, но вот в этой части кода мы «переписываем» гравитацию (ось У) и поэтому шар не упадет.

void Update() {
    rb.velocity = new Vector3 (speed, 0f,0f);
}


Я бы изменил вот так:

void Update() {
    rb.velocity = new Vector3(speed, rb.velocity.y, 0f);
}


А в целом очень даже ничего!
Sign up to leave a comment.

Articles

Change theme settings