Neural Network Racing - Part 4
Метки c#, games, genetic algorithms, neural networks, racing, unity
Итак, после того, как ИИ готово, можно перенести весь проект в Unity и сделать полноценную гонку в 3D. Экспорт трека в Unity Редактор треков, который я описывал ранее, сохраняет специальную текстуру с изображением трека. Мы ее экспортируем в проект Unity и с помощью нее формируем текстуру трека на террейне. Это делается с помощью такого кода: BuildTerrain
В результате поверх террейна накладывается наш трек: ![]() Помимо текстуры трека, мы открываем в Unity и XML файл самого трека. Модель машины Скачиваем простенькую модель машинки, у которой корпус и колеса идут отдельными мешами. К машинке вешаем Rigidbody и коллайдер. Здесь нужно более подробно остановиться на том, как будет управляться наша машинка. Поскольку нейронная сеть обучалась на плоском двумерном треке, то и ездить они должна по плоскому двумерному треку. Для этого мы загружаем трек, который использовался при симуляции и наша НС будет ездить именно в этом двумерном треке. О трехмерной модели и террейне наша система управления машинкой ничего не знает и не должна знать. Просто к двумерной позиции мы привяжем нашу трехмерную модель машинки. Из-за того, что наш симулятор ничего не знает о столкновениях и о трехмерном мире, мы не можем применить стандартную физику Unity к нашим машинкам. Поэтому, для Rigidbody нашей машинки мы выставляем свободу движения только по оси Y, а вращения - только по осям X и Z. Координаты X и Z будут выставляться из нашей двумерной модели - это координаты машины на плоскости, а вращение по оси Y будет совпадать с вращением вектора LookAt нашей машинки. Также, нам нужно выключить стандартные столкновения между машинками. Это делается через настройки коллайдеров слоев. ![]() ![]() Теперь система управления может свободно устанавливать координаты X и Z машинки, а также угол вращения по оси Y, не боясь что в это дело вмешается физика 3D движка. Однако, если совсем не моделировать столкновения между машинками - получится совсем нехорошо, машинки будут налазить друг на друга и никак не взаимодействовать между собой. Эта проблема решается созданием триггера вокруг машинки и обработкой события столкновения. Когда машинки сталкиваются между собой, мы вычисляем вектора вдоль которых нужно "растолкнуть" машинки и меняем соответствующие координаты и скорости. Но меняем их не для Rigidbody, а для исходной модели (то есть объекта Car). Скрипт обработки столкновения выглядит так: OnTriggerStay
В результате мы расталкиваем машинки, до тех пор пока их триггеры не перестанут соприкасаться. Дообучение нейронной сети При старте программы, мы загружаем обученную нейронную сеть для управления машиной. Однако тут есть две небольшие проблемы: 1) Поскольку НС у нас только одна, а ботов в игре будет много, то все боты будут ездить абсолютно одинаково. Для игры это плохо и не интересно. 2) Вторая проблема в том, что я бы хотел сделать в игре много разных треков. Конечно наша НС сможет по ним ездить. Но ее езда не будет оптимальной для данного трека. Представим себе ситуацию, что НС обучилась на сложном треке, пример которого я приводил ранее. И в то же время текущий трек намного более простой (например имеет форму круга). В таком случае нейронная сеть будет слишком осторожничать и не развивать максимально возможную скорость на данном треке. Для решения этих двух проблем мы сделаем такую вещь - мы будем дообучать нейронную сеть перед тем как запустить ботов на трек. Обучение ведется точно также как и в симуляторе - с помощью GeneticNN. Мы загрузим текущий трек, загрузим нашу НС в качестве первой особи. И затем погоняем симуляцию пройдя пару поколений. В результате мы получим популяцию НС которые будут наследниками исходной образцовой НС. При этом они все будут немного разными (за счет мутаций и рекомбинации). Таким образом мы каждому боту присвоим свою уникальную НС, и наши боты будут немного по-разному вести себя на треке. Кроме того, поскольку мы дообучаем НС на текущем треке, то генетический алгоритм отберет нейронные сети наиболее приспособленных именно к данному треку. Поскольку алгоритм симуляции очень быстр, дообучение НС занимает пару секунд и не сказывается на играбельности. Остальной код проекта в Unity я не буду описывать. Он довольно тривиальный и не имеет особого отношения к теме нейронных сетей. Результат В целом, машины управляемые нейронной сетью отлично ведут себя на треке. На длинных участках они разгоняются, в поворотах - тормозят. Траектория движения также очень хороша. НС предпочитает не входить в занос и почти весь трек они проходят без заносов. Возможно траектория и не идеальна, но она очень эффективна, вручную обогнать ботов очень тяжело. Я не смог подняться выше 6 места при соревновании с ботами. Я конечно не гонщик, и мое вождение далеко не идеально, но скорость с которой ездят боты впечатляет :) Вот как это выглядит (красная машинка управляется игроком, остальные - ботами): ![]() (если gif не открылся, скачать можно здесь) На youtube можно посмотреть как выглядит вождение глазами бота (все машинки на видео, включая желтую машинку - управляются ботами): ![]() А здесь можно скачать демо-версию игры: https://www.dropbox.com/s/obez... o.zip?dl=0 Управление - стандартное WASD, тормоз - Space. С помощью клавиш 1-7 можно переключать камеру на ботов. Клавиша 0 - переключает камеру обратно на машину игрока. Можете попробовать посоревноваться с ботами. Интересно, какое место вы займете? ;) |
Всего комментариев 4
Комментарии
-
Запись от Sanya_sa размещена 12.04.2018 в 15:56 -
Запись от bedvit размещена 12.04.2018 в 18:46 -
Отличный материал!
А почему не хотите подобное и на хабре публиковать?Запись от sldp размещена 18.04.2018 в 09:53 -
Сказать, что статьи шикарны - ничего не сказать. Такой массы примеров по нс и моделированию в рунете наверно просто нет. Да еще и в одном месте. Лично для меня одна реализация генетического алгоритма - бомба, очень интересно.
Немного недопонял момент с физикой автомобиля. При нажатии и отпускании кнопки поворота, руль не встает в исходное положение, и машина несется в заданом направлении. Получается стартуем ровно - руль вправо - машина несется вправо - руль влево - машина едет влево, ровно никак не поставить. Так и едем зигзагами.
Боты чертовски хороши - обогнать не удалось ни одного. Надо чуть попроще)
Нашел баг, на самых низких настройках графики запредельная скорость. Играть невозможно.Запись от Рядовой размещена 27.06.2018 в 13:09