Главная » Правописание слов » Как написать искусственный интеллект для игры

Слово Как написать искусственный интеллект для игры - однокоренные слова и морфемный разбор слова (приставка, корень, суффикс, окончание):


Морфемный разбор слова:

Однокоренные слова к слову:

Как я писал ИИ для пошаговой стратегии

Всем привет. Думаю, что из заголовка ясно, что речь пойдет о создании искусственного интеллекта(далее просто ИИ), о том какие решения были приняты и что в итоге получилось. Но вначале необходимо ввести Вас в курс дела.

Игра написана на языке программирования Lua, поэтому и примеры кода я буду приводить на этом языке.

Опишу некоторые детали игры, важные для ИИ:

Пока мы не будем глубоко разбираться, как ИИ принимает решения в политике, а заметим следующее:

На самом деле в игре есть только одна таблица, связанная с ИИ, и условно выглядит она так:

standard – уровень сложности. Уровней сложности несколько, и значения в разных таблицах различаются.

Третья таблица player содержит таблицы peace и war с измененными значениями. Как вы уже знаете, в игре ИИ может по-разному относиться к игроку и боту.

Значения в таблицах, я думаю, понятны по названию. Но в любом случае некоторые из них мы рассмотрим.

А пока нам нужно разобраться, как же устроен ИИ в игре. Здесь все просто, в зависимости от состояния бот может выбрать любое значение из списка. Числа, которые выше, — это вероятность наступления каждого события. Рассмотрим на примере:
pact = 0.005 – означает, что с шансом 0.005 страна предложит другой стране заключить пакт о ненападении. Да, все просто. Вы можете сказать: «Как тогда можно играть, зная, что ИИ все делает наугад?». На самом деле не совсем так и это мы разберем чуть позже.

А пока посмотрим на следующую функцию:

У каждой страны в файле сохранения есть следующие поля:

С определенным шансом страна может выдвинуть ультиматум, при выполнении которого война отменяется. Например:
Уменьшите вашу армию в провинции lipetsk до 5 000, иначе мы объявим Вам войну.

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

Есть две переменные, ответственные за шанс поддержки игрока(передать игроку золото). Первая работает всегда, кроме состояния войны со страной, для которой это рассчитывается. И вторая, с большим значением, учитывается, когда есть общий враг.

Также были добавлены разные переменные, например, страх(то насколько сильно армия противника должна превышать собственную, чтобы ИИ начал задумываться о мире). Все это сделано ради того, чтобы действия ИИ казались более логичными и понятными. Но все равно, теперь мы знаем, что на самом деле это обычная замаскированная случайность.

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

Источник

Как я свой первый ИИ писал

Привет, Хабр. История моя берёт начало в январе 2019 года.

Мы с моей тимой геймдевелоперов решили взяться за самый большой проект в нашей истории- 2Д платформер. Нет, мы не делали до этого какие-нибудь FlappyBird’ы или змейки, но объём работы в этом проекте просто сносил нам мозг. Для начала мы отказались от обычных, вертикальных лестниц, а взяли ступенчатые лестницы. Мы написали логику для дверей, которые можно было закрывать «на ключ» и прикрутили разрушаемые блоки. Наступил момент, когда надо было писать Искусственный Интеллект. Как самому опытному из нашей малоопытной команды скриптеру, честь писать ИИ выпала мне. я плакал в подушку, не понимая, что мне делать я был очень горд тем, что именно я напишу одну из самых сложных механик в нашем проекте.

Этап 1: поиск пути и движение по пути

Этап 1.1: Поиск пути

Так как основные локации у нас будут не на открытом воздухе, а в зданиях, то нужно было сделать поиск маршрута среди десятков дверей, лестниц и комнат. Подумав, мы с тимлидом решили, что стоит сделать некую пародию на алгоритм A*, где у нас будут узлы, между которыми будет бегать бот. сделали тестовую сцену, поставили узлы, для наглядности повесили на них SprateRenderer’ы. А что делать дальше?

С этим вопросом в голове я ходил 3 дня. Пока один мой товарищ не предложил интересный алгоритм, когда узлы будут возбуждаться, подобно нейронам головного мозга.

Итак. Есть узел A, около которого стоит ИИ и узел Б, к которому ИИ должен прийти. выдали всем Узлам свой ID и пометили соединенные узлы, к которым они будут отправлять сигнал. У каждого узла была своя булевая переменная «isChecked» и переменная «triggeredBy», в котором хранился ID узла, который его «возбудил». Так, когда затронут узел Б, он пройдёт по цепочке к узлу А, узнавая все ID узлов, которые прошёл сигнал. Так я получал путь из ID узлов, которые должен пройти бот. Если вы вдруг не поняли, как это работает, то я расскажу вам сказку.

Однажды Ивану нечего было делать, и поэтому он решил составить своё фамильное древо. К несчастью у него не хватало информации для воплощения этой идеи в жизнь. Иван был так увлечён этой идеей, что решил, что добравшись до главного прародителя он сможет обнаружить своих неожиданных родственников. Иван знал, где он может встретиться со своим отцом, чтобы поговорить и направился туда. Отец рассказал ему, что деда Ивана звали Iван и рассказал, где его можно найти. Иван нашёл Iвана, и тот рассказал, что прадед Ивана мог знать этого прародителя лично, но он давно помер. Иван посветил половину жизни изучению тёмных искусств, но в итоге смог воскресить своего прадеда. Прадед сказал, что его прародитель является оборотнем и что зарыто его тело на опушке у трёх сосен. Иван пошёл туда и обнаружил, роющего могилу человек. Оказалось, что этот человек – двеннадцатиюродный брат Иван. Иван сильно удивился тому, что они пришли к одному месту, но брат оказался программистом и всё объяснил.

– Здесь работает принцип навигации из моей любимой игры *название*!

– И в чём же он заключается?

– От каждого наследника можно придти к общему родителю системы, если в этой системе каждый наследник знает лично своего родителя.

Получился вот такой результат:

Это массив int-переменных, которые означают ID узлов, которые должен пройти юнит.

Этап 1.2.1: движение по пути

У меня есть список ID узлов, у меня есть бот. Что дальше? А дальше то, что надо двигать бота по этому пути.

Ну я прикинул такой вариант: дошёл бот до узла, поставил галочку, посмотрел, что там дальше, пошёл к следующему узлу. Сделал. Заработало. Я был рад… Но…

Этап 1.2.2: лестницы и их взаимодействие с ИИ

Как говорил один чёрно-белый герой: «Лестницы… мой главный враг..»

Нужно было определить, следующий узел находится над ИИ, под или на уровне. В зависимости от этой информации он будет проходить мимо лестницы(игнорировать коллизию), или забираться на неё(взаимодействовать с коллизией). Ох и много нервных клеток полегло на этой битве с движком… На форумах вычитал, что можно расставить всё по слоям и во вкладке Edit->Physics2D можно настроить игнорирование коллизий одного слоя и другого. Всё заработало!
Осталось только научить его открывать двери. Тут проблем не возникло.

Этап 2: Эмоции и реплики

Этап 2.1: Эмоции

Да, мы решили приделать эмоции… И реплики.

Эмоции будут выделяться выражением лица и анимациями действий.

Реплики будут отображаться текстом над головой.

Эмоции я прикрутил на одном дыхании… Для этого я уже сделал переменную «emotionID», которая хранила в себе ID эмоции. А вот реплики…

Этап 2.2: Реплики

Для красоты сделал отдельный класс Phrases

Сделал массив этого класса. Дальше просто в зависимости от emotionID ставил любую фразу из списка. Обновлял раз в N секунд.

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

Конец.

От большой, неоплачиваемой работы мы быстро устали… Присоединение нового кодера не помогло… Команда развалилась… Код всё-ещё лежит на облаке Unity.

Конечно, не так давно начала зарождаться идея продолжить проект, но уже с дальнейшей монетизацией… Если что-то получится, то я, пожалуй, напишу всю историю разработки. Но на этом мой рассказ про начинающего скриптера и ИИ заканчивается.

Источник

Пусть компьютер сам принимает решение или пишем ИИ для игры вместе

Вы когда-нибудь задумывались о том, насколько просто написать свой искусственный интеллект, который сам будет принимать решения в игре? А ведь это действительно просто. Пусть для начала он принимает случайные решение, но позже вы можете его воспитать, научить анализировать ситуацию, и тогда он станет принимать осознанные решения. В этой статье я расскажу, как я писал своего бота, а также покажу, как вы за несколько минут можете написать своего. Наш компьютер будет играть в клон игры Трон, а точнее в ту часть, где нужно на мотоцикле победить врагов.


Под катом gif-файлов мегабайт на 10.

Об игре

В игре вы управляете мотоциклом, который оставляет за собой стену из света. Игровое поле ограничено, а у соперников такие же мотоциклы. Мотоцикл едет постоянно, вы лишь можете поворачивать. Свободное место на поле кончается, и избегать препятствия становится сложнее. Побеждает тот, кто дольше всех продержится. Клон игры я сделал браузерным многопользовательским с использованием node.js и socket.io. Управление из двух кнопок – поворот влево и поворот вправо.

Интерфейс бота

При поступлении от сервера команды обновления данных мотоциклов (было совершено их передвижение) я проверяю, есть ли у меня вообще подконтрольный мотоцикл, не столкнулся ли он еще и был ли он перемещён, и, в случае успеха, я вызываю основной метод для работы ИИ — update().
Интерфейс готов, теперь можно добавить сам ИИ.

Искусственный интеллект

Когда я решил написать бота, я понятия не имел, как это можно сделать. Я попробовал очень простой код:

Поведение было примерно таким:

Я смотрел на него и испытывал большую радость, мне казалось, что он теперь самостоятельный. Казалось, что он сам ищет попытки выжить, бьётся там, как живой. Трогательное зрелище.

Но хотелось, чтобы он жил как можно больше. Я стал искать информацию о том, как пишут ИИ к играм. Нашел статьи, которые описывали разные подходы. Но я искал что-то чрезвычайно простое. Я нашел на хабре в одной из статей про бота для игры вроде Zuma упоминание волнового метода. Он же алгоритм Ли. Мне он показался очень простым и подходящим. Это алгоритм поиска кратчайшего пути из одной точки в другую по полю, где клетки могут быть либо свободными, либо занятыми. Суть простая. Мы начинаем из точки назначения, присваиваем ей значение 1 и помечаем все соседние свободные клетки цифрой на единицу больше. Затем берём все соседние свободные помеченных и снова помечаем на единицу больше. Так расширяемся на всё поле, пока не дойдем до точки назначения. А путь строим поиском из соседних по уменьшению числа, пока не дойдем до 1. Я смотрел алгоритмы поиска кратчайших путей в графах, но этот мне показался наиболее подходящим.

Я перенёс алгоритм копипастой из страницы в вики, дал ему имя BotSocket.prototype.algorithmLee. Для поля я создал сначала объект battleground, в котором при каждом обновлении помечал занятые точки с их координатами. А в алгоритме Ли сводил это поле к такому же, но с шагом 1.

Нужно было как-то определять точку назначения. Я решил выбирать её случайно через определенные интервалы времени. Сделал метод для поиска случайной свободной точки на поле:

Теперь я мог переписать update:

Здесь упоминается метод moveToPoint, который поворачивает, если нужно, чтобы достигнуть первую точку из кратчайшего пути с учётом текущего направления.

Позже я решил сделать ботов более агрессивными и вместо случайной желаемой точки, я искал точку впереди врагов, чтобы перекрыть им путь. Или чтобы они не играли так долго сами с собой.

Бот на стороне клиента

Я решил попробовать перенести бота на клиентскую часть. Так как проект на node.js, я могу использовать написанный код для бота и на стороне клиента. Для этого я расширил BotSocket отдельным клиентским файлом, который переопределял методы emit() и control(), чтобы правильно взаимодействовать с сервером без ссылки на объект game.
Локально всё работало отлично, а после деплоя на удалённый сервер была какая-то странная картина:

Долго думая, я понял, что дело в задержке. Бот отправлял команду поворота, но она доходила после обновления его позиции на сервере, отчего он часто не мог попасть на прямой путь к желаемой точке. Но я хотел нормального бота на клиентской стороне. Поэтому решил учитывать задержку. Для этого написал снова расширение BotSocket. Статья получается длинной, так что опишу основные решения. Перед вызовом алгоритма Ли вместо текущей точки я подставлял прогнозируемое положение с учетом текущего положения и направления, а так же множителя задержки. Множитель задержки – это число, во сколько раз превосходит задержка частоту обновления положения на сервере. Предсказание будущей точки мне еще понадобилось в методе moveToPoint().

Предсказание работало, если играл один. Но если были другие участники, то бот не учитывал это и направлял туда, где через некоторое время уже проехал другой игрок. Для решения этой проблемы я изменил метод, который помечает клетки поля занятыми. Я стал их помечать занятыми в некотором радиусе движения мотоциклов. Радиус зависит от множителя задержки.
Предварительно я снабдил бота функциями отладки, который рисовали на поле желаемую точку и занятые точки. Моя версия клиентского бота с учетом задержки теперь двигается так:

Мой красненький, остальные серверные.

Самое важное – попробуйте сделать бота сами

Основная цель этой статьи – пробудить интерес к написанию бота. Я сделал много, чтобы победить вашу лень. Для этого я добавил возможность подгружать свой собственный скрипт с ботом, который будет расширять мой базовый клиентский класс. Зайдите на проект и нажмите на текст «Show options for room with your own bot», а затем на кнопку «Create room for test your own bot». Будет создана комната, где можно легко применять ботов, по умолчанию вашим ботом будет бот без учета задержки. Теперь настало время для вашего кода.
Два простых варианта для использования вашего кода в деле, используйте любой:

Если вы определились с методом ввода вашего кода, попробуйте переопределить методы класса BotSocket. Для начала самое простое:

После этого пересоздайте объект botSocket, введя

При этом код на странице сам пересоздаст и заполнит объект. Этим вы измените стандартное поведение бота на случайное. А дальше уже дело для вашей фантазии или глубоких знаний.
Вы так же можете подключить скрипт моего улучшенного бота с учетом задержки, вставив в url для бота https://raw.github.com/rnixik/tronode-js/master/public/javascripts/MyBotSocketClient.js

Заключение

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

Если у вас нет под рукой node.js, вы можете воспользоваться развернутыми мной приложениями:

1) tronode.livelevel.net — самая дешевая VPS на DigitalOcean,
2) tronode-js.herokuapp.com — бесплатная виртуальная единица на Heroku.

Первый, скорее всего, первым может не справиться с нагрузкой, а второй на некоторых компьютерах сбрасывает socket.io-транспорт в xhr-polling, из-за этого игра очень сильно лагает.
Если вы хотите узнать больше, о том, как я программировал игровую логику, то можете прочитать здесь. Там же о развертке node.js и немного о графической части.

Если у вас нет аккаунта на хабре, то задать вопросы или прислать свои интересные предложения можете мне на почту dev@1i1.be.

Источник

Практический геймдизайн: создание ИИ для своей игры

Некоторое время назад мне понадобилось разобраться в создании ИИ для игр, и вот, что я успел выяснить.

Когда мне понадобиться разработать ИИ, я последовательно пройду следующие пункты:

Сегодня мы поговорим о первом из них.

Подумайте, кого вы обычно называете умными людьми. Мое мнение такое:

Во-первых, умный человек должен обладать хорошим уровнем осознания. Он умеет анализировать мир и происходящее в нем, и делать правильные выводы.

Но просто получить информацию недостаточно, нужно отреагировать. Принять правильное решение. Чем решение эффективнее, тем оно умнее.

Тут перед нами возникает первая проблема и вопрос в создании ИИ.

Но поскольку это сравнительные качества, нам нужен достойный соперник для их подтверждения. Никто не хочет быть умнее, чем табуретка, или сильнее младенца.

Вы сейчас разрабатываете игру? Вы знаете, какие навыки требуются для нее? Если нет, то самое время подумать об этом.

Поскольку мы говорим о шутерах, предлагаю выделить следующие навыки:

Про принятие решений давайте скажем чуть больше.

Может быть не очевидно, но принимать решения нужно в любой игре. Посмотрите на этот график.

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

Или вот сложнее: вы бежали к двери в Black Ops 4, а из нее, у вас перед носом, выскочил другой игрок. Нужно определить, что выгоднее: открывать огонь, или шагнуть ему на встречу, и вломить прикладом. Это зависит от кучи факторов: расстояние между вами, его здоровье, направление движения. Сама по себе задача простая, но необходимость решить ее за доли секунды, усложняет ее кардинально.

После того, как мы определились с навыками, пора внедрить в ИИ поведение, которое заставит игрока их использовать.

Давайте рассмотрим как это сделать на примитивном примере.

По этой ссылке можно скачать прототип top-down шутера.

Кнопки 1-8 включают разные настройки поведения, которые иллюстрируют определенный уровень проработанности ИИ.

Запускайте прототип, и

На этой фазе у игрока и противника отключен урон, поэтому игры как таковой нет. Здесь нельзя ни выиграть, ни проиграть.

Поторопитесь открыть огонь! Теперь вы можете наносить урон своими выстрелами, как и ИИ-оппонент. Но игры все еще нет.

Чтобы погибнуть, нужно постараться. Специально подождать, пока противник нанесет вам урон, а потом вступить в бой. Иначе он погибает первым, благодаря пониженным характеристикам.

На этой фазе противник получает почти двойное повышение урона. Стреляйте как можете, но вы все равно будете умирать раз за разом.

Это и есть тот момент, когда интерактивное, но бессмысленное действо превращается в игру. Игрок спрашивает: что мне сделать, чтобы победить? Мы должны дать ему ответ.

Обратите внимание на появившиеся красные полоски, отражающие сектор стрельбы противника.

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

Начинайте двигаться по кругу вокруг противника. Вы увидите, что его прицел немного не успевает за вами. К чему это приводит?

Игра вынуждает вас использовать навык управления. Это и есть ответ на вопрос игрока, который указывает ему правильное поведение.

Управление усложняется. Теперь центр круга, по которому нужно двигаться, все время меняется.

Давайте снова выключим нанесение урона, чтобы спокойно посмотреть на ситуацию.

На этой фазе вместо одного противника, появляются сразу пять. Но на геймплей это кардинально не влияет. Поскольку противники держатся поблизости, и перемещаются в примерно одинаковой области, игроку не нужно менять свое поведение.

А что если научить их работать в группе?

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

Ранее в фазе 4 мы допустили ошибку. Мы позволили игроку «ломать» наш ИИ.

Такое происходит, когда поведение бота недостаточно проработано, и может быть эксплуатированно игроком.

В фазе 3 алгоритм прицеливания работает так: есть направление в котором расположен игрок, и есть текущее направление прицела. Текущее направление сдвигается к игроку со скоростью 0.7 градусов в кадр.

В фазе 8 скорость прицеливания подвешена на «резинку». Теперь она тем больше, чем больше разница между текущим направлением прицела, и направлением на игрока.

Если бы мы задались целью довести этот прототип до ума, совершенствовать поведение ботов можно было очень долго. Всегда стоит думать о том, каким способом можно сломать поведение вашего ИИ, и предотвращать это.

Вы получили основу для начала разработки своего ИИ. Попробуйте пройти те же шаги, что и я в этой статье

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

Источник

Создание простого ИИ на C# в Unity

Почти любой игре необходим взаимодействующий с пользователем искусственный интеллект (AI), чаще всего в виде враждебной игроку силы. В некоторых случаях ИИ должен помогать игроку, в других — бороться с ним, но у всех управляемых компьютером персонажей существует некоторое сходство. В зависимости от требований проекта ИИ может использовать простые или сложные поведения. Такими требованиями могут быть дипломатия с другим игроком или простое блуждание вперёд-назад по платформе. Как бы то ни было, необходимо сделать так, чтобы ИИ качественно выполнял свою работу.

В этом проекте я продемонстрирую очень простой искусственный интеллект. Допустим, мы создаём игру, в которой игрок должен тайком пробраться рядом с вражеским штабом. Когда игрока замечает камера слежения, рядом создаются враги и в течение короткого промежутка времени преследуют игрока. Именно это мы и реализуем в проекте на простейшем уровне. Завершив проект, вы получите управляемый объект игрока, круг, используемый в качестве камеры врага, и объект врага, который будет преследовать игрока, когда о его присутствии сообщит объект камеры.

Подготовка

Для начала нам нужно создать 3D-проект. Нажмите на кнопку New в верхней части окна после запуска Unity, как это показано на рисунке 1.

Рисунок 1: создание нового проекта

Назовите свой проект AI и убедитесь, что он является 3D-проектом. Выбрав место на компьютере для хранения проекта, нажмите на кнопку Create Project внизу, показанную на рисунке 2.

Рисунок 2: экран настройки проекта

После создания проекта нам первым делом нужно настроить папки в окне Assets, чтобы упорядочить свою работу. Нажмите правой кнопкой на окне Assets и выберите Create → Folder для создания новой папки. Назовите эту папку Materials. Затем создайте вторую папку и назовите её Scripts. На рисунке 3 показано, как это должно выглядеть.

Рисунок 3: создание новой папки

После всего этого окно Assets должно выглядеть так, как показано на рисунке 4.

Далее создадим пол, на котором будут стоять все объекты. В окне Hierarchy выберите Create → 3D Object → Plane, чтобы создать объект-плоскость, которая будет использоваться в качестве пола.

Рисунок 5: создание объекта Plane.

Назовите этот объект Floor и измените его значение X Scale на 7, а значение Z Scale — на 3. После этого окно Inspector с выбранным объектом Floor должно выглядеть так, как показано на рисунке 6.

Рисунок 6: задание свойств объекта Floor.

Теперь нам нужно создать новый материал для Floor, чтобы отличать его от остальных объектов, которые будут размещены в сцене. В папке Materials окна Assets создайте новый материал, нажав правой кнопкой на окно Assets и выбрав Create → Material.

Рисунок 7: создание нового материала

После завершения назовите материал Floor.

Рисунок 8: материал Floor.

В верхней части окна Inspector с выбранным материалом Floor выберите color picker.

Рисунок 9: выбор color picker.

Разумеется, вы можете выбрать для пола любой цвет, но в этом примере я выбрал красно-коричневый цвет, как показано на рисунке 10.

Рисунок 10: color picker.

Выберите объект Floor в окне Hierarchy, и в компоненте Mesh Renderer выберите маленькую стрелку рядом с Materials.

Рисунок 11: подготовка к изменению материала.

Перетащите материал Floor из окна Assets в поле Element 0 компонента Mesh Renderer в окне Inspector.

Рисунок 12: задание материала Floor в качестве материала объекта Floor.

Закончив с объектом Floor, мы дожны создать вокруг области стены, чтобы игрок не мог свалиться с края. Снова заходим в Create → 3D Object → Plane для создания новой плоскости. Назовём эту плоскость Wall и выставим ей те же размеры, что и у Floor, то есть X Scale со значением 7 и Z Scale со значением 3. Затем создадим ещё три стены, выбрав объект и трижды нажав Ctrl + D. После этого разместим стены вокруг пола в соответствии с данными из таблицы.

Название Position X Position Y Position Z Rotation X Rotation Z
Wall -35 21 0 0 -90
Wall (1) -1 11 -15 90 0
Wall (2) -1 11 13.5 -90 0
Wall (3) 34 21 0 0 90

Таблица 1: позиции и повороты всех объектов Wall.

Завершив всё это, нужно изменить положение камеры, чтобы она смотрела на пол сверху. Выберите объект Main Camera и задайте для Y Position значение 30, для Z Position значение 0, а X Rotation — значение 80.

Рисунок 13: настройка объекта камеры.

Сцена подготовлена, поэтому настало время создания персонажа игрока. В окне Hierarchy нажмите на Create → 3D Object → Sphere, чтобы создать объект-сферу. Назовите этот объект Player, а затем нажмите на кнопку Add Component в нижней части окна Inspector.

Рисунок 14: добавление нового компонента.

Теперь найдите Rigidbody. После этого выберите из списка компонент Rigidbody и добавьте Rigidbody к объекту Player.

Рисунок 15: добавление компонента Rigidbody.

Далее нужно присвоить игроку тэг, который позже пригодится нам в коде. Нажмите на раскрывающееся меню Tag в левом верхнем углу окна Inspector и выберите тэг Player.

Рисунок 16: задание нового тэга.

Рисунок 17: размещение игрока.

Чтобы наш будущий код работал правильно, нам, разумеется, нужно прикрепить его к объекту. Снова заходим в окно Hierarchy и на этот раз выбираем Create → 3D Object → Cube. Назовём этот куб Guard, добавим к нему компонент Rigidbody и компонент NavMesh Agent с помощью кнопки Add Component в окне Inspector. Далее поместим его где-нибудь в верхнем левом углу сцены. После этого окно Inspector объекта Guard будет выглядеть следующим образом:

Рисунок 18: объект Guard в окне Inspector.

И этот объект должен быть расположен так:

Рисунок 19: Размещение объекта Guard.

Наконец, нам потребуется объект, используемый в качестве «глаз» объекта Guard, который будет уведомлять Guard о том, что его касается игрок. В последний раз перейдите в окно Hierarchy и выберите Create → 3D Object → Sphere для создания ещё одного объекта-сферы. Назовите этот объект Looker. На этот раз нам не нужно добавлять к нему никаких других компонентов. Однако мы изменим размер объекта. Выбрав Looker, измените следующие переменные компонента Transform в окне Inspector.

Рисунок 20: размещение объекта Looker.

Настало подходящее время для того, чтобы придать Looker уникальный материал, чтобы было заметно, что его стоит избегать. В папке Materials окна Assets нажмите правой клавишей мыши и создайте новый материал. Назовите его Looker и задайте ему ярко-красный цвет. После этого назначьте этот материал в качестве материала объекта Looker, чтобы изменить его цвет. После этого сцена должна выглядеть следующим образом:

Рисунок 21: объект Looker с новым материалом.

Единственное, что нам осталось — создать навигационный меш для Guard, по которому он сможет перемещаться. В верхней части редактора Unity есть меню Window. Выберите Window → Navigation, чтобы открыть окно Navigation, показанное на рисунке 22.

Рисунок 22: окно Navigation.

Выберите объект Floor в Hierarchy, а затем в окне Navigation поставьте флажок Navigation Static.

Рисунок 23: Navigation Static.

Далее выберем опцию Bake в верхней части окна.

Рисунок 24: переключение на меню Bake.

Откроется меню Bake, в котором можно изменять свойства навигационного меша, который мы собираемся создать. В нашем примере ничего изменять не требуется. Достаточно нажать на кнопку Bake в правой нижней части.

Рисунок 25: создание нового навигационного меша.

На этом этапе Unity попросит сохранить сцену. Сохраните её, после чего будет создан навигационный меш. Теперь сцена будет выглядеть так:

Рисунок 26: текущая сцена с добавленным навигационным мешем.

Теперь всё в Unity настроено, поэтому настало время для создания скриптов, необходимых для работы проекта. В окне Assets нажмите правой клавишей мыши и выберите Create → C# Script. Назовите этот скрипт Player. Повторите эту операцию ещё два раза, создав скрипты с названиями Guard и Looker.

Рисунок 27: создание нового скрипта.

После этого папка Scripts в окне Assets будет выглядеть так:

Рисунок 28: папка Scripts.

Первым мы начнём писать код скрипта Player. Дважды щёлкните по скрипту Player в окне Assets, чтобы открыть Visual Studio и приступить к созданию кода.

Скрипт Player достаточно прост, всё что он делает — позволяет пользователю перемещать объект-мяч. Под объявлением класса нам нужно получить ссылку на компонент Rigidbody, который мы ранее создали в проекте.

Сразу после этого в функции Start мы прикажем Unity сделать текущий компонент Rigidbody объекта Player значением rb.

После этого скрипт Player будет выглядеть так:

Рисунок 29: скрипт Player на текущий момент.

Теперь, когда значение rb присвоено, нам нужно позволить объекту Player двигаться при нажатии клавиш со стрелками. Для перемещения объекта мы будем использовать физику, применяя силу к объекту при нажатии пользователем клавиш со стрелками. Для этого достаточно добавить в функцию Update следующий код:

На этом мы завершили скрипт Player. Готовый скрипт будет выглядеть следующим образом:

Рисунок 30: готовый скрипт Player.

Сохраните свою работу и вернитесь в Unity. На этот раз выберите в окне Assets скрипт Guard. Чтобы заставить код для Guard работать, нужно добавить в верхнюю часть скрипта конструкцию using.

Далее объявим следующие переменные сразу после объявления класса.

В качестве значения переменной player объекта Guard используется объект Player. Она пригодится нам позже, когда мы прикажем объекту Guard преследовать игрока. Затем объявляется переменная navmesh для получения компонента NavMeshAgent объекта. Её мы используем позже, когда Guard начнёт преследовать игрока после того, как узнает о том, что игрок касается объекта Looker. В функции Start нам нужно задать в качестве значения переменной navmesh компонент NavMesh Agent объекта:

Затем в функции Update мы добавим единственную строку кода:

Эта строка задаёт точку назначения для объекта Guard. В нашем случае она будет брать текущую позицию объекта Player и перемещаться к этой точке. После срабатывания объект будет постоянно преследовать игрока. Вопрос в том, как выполняется процесс срабатывания? Он будет закодирован не в скрипте Guard, а в скрипте Looker. Прежде чем переходить к скрипту Looker, посмотрите на рисунок 31, чтобы сверить свой код скрипта Guard.

Рисунок 31: готовый скрипт Guard.

Внутри Looker нам снова нужно объявить следующие переменные:

После этого закомментируем функцию Start, которая в этом скрипте нам не нужна. Перейдём к функции Update и добавим следующий код:

Именно здесь происходят основные действия проекта, поэтому давайте проанализируем код. Во-первых, в зависимости от значения булевой переменной movingDown, объект, к которому прикреплён этот скрипт, будет двигаться вверх или вниз. Как только он достигнет определённой точки, то изменит направление. Далее Looker снизит значение сброса на основании реального времени. Как только таймер станет меньше нуля, он возьмём скрипт Guard из объекта Guard и отключит его, после чего объект Guard начнёт перемещаться к последней известной до этого моменрта позиции игрока, а затем остановится. Looker также снова включает его коллайдер, чтобы весь процесс мог начаться заново. Теперь наш скрипт выглядит следующим образом:

Рисунок 32: скрипт Looker.

Кстати о коллайдерах: настало время создать код коллизии, сбрасывающий таймер Looker и включающий скрипт Guard. В функции Update создайте следующий код:

OnCollisionEnter Unity автоматически распознаёт как код коллизии, а поэтому выполняет его при возникновении коллизии с другим объектом. В нашем случае он сначала проверяет, имеет ли столкнувшийся объект тэг Player. Если нет, то он игнорирует остальную часть кода. В противном случае он включает скрипт Guard, задаёт таймеру reset значение 5 (то есть пять секунд), и отключает его коллайдер, чтобы игрок по-прежнему мог двигаться сквозь объект и случайно не застрял в объекте Looker. Функция показана на рисунке 33.

Рисунок 33: код коллизии для Looker.

На этом весь код проекта готов! Можно сделать ещё пару вещей, прежде чем закончить проект. Сохраните всю работу и вернитесь в Unity.

Завершение проекта

Для завершения проекта нам достаточно прикрепить скрипты к соответствующим объектам и задать несколько переменных. Во-первых, перейдите из окна Navigation в окно Inspector:

Рисунок 34: переход в окно Inspector.

После этого начнём с объекта Player. Выберите его в окне Hierarchy, а затем в нижней части окна Inspector нажмите на кнопку Add Component и добавьте скрипт Player. На этом объект Player завершён.

Рисунок 35: компонент скрипта Player.

Далее выберите объект Guard. Как и раньше, прикрепим скрипт Guard к объекту. На этот раз нам понадобится сообщить Guard, кто является игроком. Для этого перетащите объект Player из Hierarchy в поле Player компонента скрипта Guard, как показано на рисунке 36.

Рисунок 36: делаем объект Player значением поля Player.

Также нам нужно отключить скрипт Guard. В нашем проекте Guard будет преследовать игрока после включения его скрипта. Этот скрипт Guard должен включаться только после того, как игрок коснётся объекта Looker. Всё, что нужно сделать — снять флажок рядом с текстом Guard (Script) в компоненте:

Рисунок 37: отключение скрипта Guard.

Наконец, перейдём к объекту Looker и прикрепим к нему скрипт Looker. На этот раз объекту Looker потребуется объект Guard в качестве значения его переменной Guard. Так же, как мы назначали объект Player переменной Player скрипта Guard, мы сделаем то же самое с объектом Guard и скриптом Looker. Перетащите Guard из Hierarchy в поле Guard скрипта Looker. И на этом проект завершён! Нажмите на кнопку Play в верхней части редактора Unity, чтобы проверить свой проект.

Рисунок 38: тестирование проекта.

Попробуйте переместить объект Player в объект Looker (не забывайте, что перемещение выполняется стрелками!). Заметьте, что после этого объект Guard начнёт преследовать игрока. Он будет продолжать преследование примерно 5 секунд, после чего сдастся.

Рисунок 39: полностью готовый проект в действии.

Заключение

Этот ИИ очень прост, но его запросто можно расширить. Допустим, если мы представим, что объект Looker — это камера, а охранник смотрит через неё, чтобы найти вас, то будет логично дать объекту Guard собственную пару глаз. Игрок может проходить рядом с камерами, но они должны учитывать и глаза охранника. Также можно скомбинировать этот проект с концепцией поиска пути: дать охраннику путь, по которому он будет следовать, создав таким образом более интересную для игрока среду.

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

Источник

Теперь вы знаете какие однокоренные слова подходят к слову Как написать искусственный интеллект для игры, а так же какой у него корень, приставка, суффикс и окончание. Вы можете дополнить список однокоренных слов к слову "Как написать искусственный интеллект для игры", предложив свой вариант в комментариях ниже, а также выразить свое несогласие проведенным с морфемным разбором.

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



Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *