Professional Documents
Culture Documents
MKA GD Unreal Urok 10 1571379780
MKA GD Unreal Urok 10 1571379780
Development
Unreal Engine
MIDDLE
Урок 10
Infinity runner
2
Infinity runner
Infinity runner
Infinity runner — это еще одна разновидность игр,
требующих от игроков быстрой реакции. Данный жанр
отличается незамысловатым геймплеем. Главному пер-
сонажу предстоит бежать вперед по бесконечно генери-
руемому миру, полному опасностей и препятствий. По-
путно ему предстоит собирать определенные предметы
и бонусы, необходимые для прокачки. Со временем ско-
рость бега может увеличиться, а препятствия будут ста-
новиться все сложнее.
Самым ярким представителем данного жанра можно
назвать игру Subway Surfers, разработанную в 2012 году
в Дании компаниями Kiloo и SYBO Games. В ней игро-
кам предстоит руководить персонажем, который пыта-
ется спастись от полисмена с собакой, убегая по желез-
нодорожным путям (рис. 1).
Рисунок 1
3
Урок 10
Рисунок 2
Прежде всего нам понадобится новая сцена от треть-
его лица. Давайте немного поменяем местоположение
стандартной камеры, которая смотрит в спину персона-
жу. В играх, наподобие Subway Surfers, камера смотрит
сверху вниз. Чтобы добиться такого же эффекта, откроем
блупринт ThirdPersonCharacter и выделим родительский
объект CameraBoom, который содержит в себе саму ка-
меру. После этого обратимся к окну настроек и повысим
значение Socket Offset по оси Z до 100 (рис. 3).
4
Infinity runner
Рисунок 3
В раннерах персонаж двигается вперед автоматиче-
ски, без вмешательства игрока. Чтобы заставить наше-
го персонажа беспрерывно двигаться вперед, перейдем
в Event Graph, отыщем ветку Movement input и удалим
ноду InputAxis MoveForward (рис. 4).
Рисунок 4
Вместо нее необходимо добавить другую ноду — Event
Tick, чтобы анимация бега персонажа просчитывалась
в каждом кадре (рис. 5).
5
Урок 10
Рисунок 5
Теперь можно запустить проверку игры: наш персо-
наж должен бежать вперед без остановок.
Далее необходимо настроить логику поворота. Для
этого создадим новую переменную CanTurn типа Bool-
ean (рис. 6).
Рисунок 6
Еще одна переменная, которую необходимо создать, —
это DesiredRotation c особым типом Rotator. Именно она
будет отвечать за поворот персонажа в требуемом на-
правлении (рис. 7).
6
Infinity runner
Рисунок 7
Чтобы персонаж реагировал на команды кнопок, под-
ключим переменную Can Turn к ноде клавиши А. Данная
клавиша по умолчанию отвечает за поворот влево (рис. 8).
Рисунок 8
Также, чтобы правильно задать угол и направление
поворота, подключим ноду Desired Rotation к функции
CombineRotation. Зададим требуемое значение поворо-
та: -90° по оси Z, то есть влево (рис. 9).
7
Урок 10
Рисунок 9
После этого соединим две ветки с помощью ноды De-
sired Rotation со значением Set (рис. 10).
Рисунок 10
Такой же скрипт создадим для клавиши D, которая
отвечает за поворот вправо. Единственное отличие —
угол поворота должен равняться 90° (рис. 11).
Рисунок 11
8
Infinity runner
Рисунок 12
Если вам необходимо быстро сгруппировать готовую
ветку, можно воспользоваться функцией комментиро-
вания. Для этого достаточно выделить все необходимые
ноды и нажать клавишу С. В результате будет создана
специальная группирующая рамка, которую можно под-
писать соответственно содержимому (рис. 13).
Рисунок 13
9
Урок 10
Рисунок 14
Ссылку на данный ивент также нужно добавить в скрипт
Event Tick в блупринте персонажа (рис. 15).
Следующее, что необходимо сделать, — сформиро-
вать беговой трек, который будет бесконечно спаунить-
ся, расширяя границы мира.
10
Infinity runner
Рисунок 15
Для этого создадим новый блупринт типа Actor и пе-
реименуем его в BP_FloorTile (рис. 16).
Рисунок 16
Откроем редактор и добавим в данный блупринт Static
Mesh, который назовем Floor. Сразу зададим ему значе-
ния Scale по трем осям: 10, 10, 0.1. Подобные параметры
позволят превратить меш в плоскость (рис. 17).
Рисунок 17
11
Урок 10
Рисунок 18
Помимо самого пола, необходимо создать бортики,
чтобы персонаж случайно не слетел с трека во время бега.
Для этого дважды продублируем компонент Floor, переи-
менуем новые объекты в Wall и поменяем значения Scale,
чтобы получить небольшие вертикальные стены (рис. 19).
Рисунок 19
12
Infinity runner
Рисунок 20
Следующий компонент, который необходимо до-
бавить, — это стрелка (Arrow). Данный элемент будет
указывать на место спауна следующего участка дороги.
Переименуем его в AttachPoint и сдвинем по оси Х на
1000 единиц (рис. 21).
Рисунок 21
После этого создадим новую функцию GetAttachTrans-
form с одноименным исходящим параметром типа Trans-
form (рис. 22).
Рисунок 22
13
Урок 10
Рисунок 23
Прежде, чем тестировать игру, давайте создадим но-
вый уровень. Для этого откроем меню File => New level
(рис. 24).
Рисунок 24
14
Infinity runner
Рисунок 25
Далее откроем блупринт самой игры — ThirdPerson-
GameMode (рис. 26).
Рисунок 26
15
Урок 10
Рисунок 27
Подключим к данной функции ноду Spawn Actor from
Class с классом BP_FloorTile. Также создадим новую ло-
кальную переменную Next Spawn Point (ПКМ => Promote
to Variable), которую подключим в строку Spawn Trans-
form (рис. 28).
Рисунок 28
В свою очередь SpawnActor должен обращаться к са-
мому объекту — блупринту BP_FloorTile, и присоединять
его в следующей точке спауна (рис. 29).
Также создадим ссылку на данную функцию в ивенте
BeginPlay, чтобы скрипт срабатывал сразу после запуска
игры. Дополнительно добавим ноду ForLoop, которая по-
зволить спаунить несколько частей трека одновременно.
16
Infinity runner
Рисунок 29
Рисунок 30
Далее вернемся в блупринт BP_FloorTile и добавим
в него новый компонент Box Collision с названием EndTrig-
ger. Пройдя через данную зону, персонаж сможет совер-
шить резкий поворот вправо или влево (рис. 31).
Рисунок 31
17
Урок 10
Рисунок 32
Дополнительно поменяем Collision Preset на Overlap-
OnlyPawn (рис. 33).
Рисунок 33
18
Infinity runner
Рисунок 34
Данная нода должна обращаться к самому персона-
жу и блупринту GameMode, после чего добавлять новый
блок в конце существующего трека (нода Add Floor Tile)
(рис. 35).
Рисунок 35
Также, чтобы не засорять уровень, добавим в скрипт
ноду DestroyActor, которая будет удалять пройденные
участки пути. При этом следует учесть время, необхо-
димое персонажу на прохождение трека. Если блоки бу-
дут удаляться слишком быстро, персонаж просто упадет
с трека. Эту задачу легко решить с помощью ноды Delay
со значением Duration=2 (рис. 36).
19
Урок 10
Рисунок 36
Теперь создадим новый блупринт с классом Actor для
предметов сбора. Переименуем его в BP_Item (рис. 37).
Рисунок 37
В редакторе данного блупринта добавим новый ком-
понент Static Mesh. Как говорилось ранее, мы создаем
игру в стиле Fortnite. Для этого в качестве собираемых
предметов будем использовать не стандартные монеты,
а ящики с припасами. Подобную модель можно легко най-
ти в интернете на специализированных сайтах. Также не
забываем затекстурировать меш (рис. 38).
Зададим Collision Preset для данного объекта — Over-
lapOnlyPawn (рис. 39).
Дополнительно можно добавить в иерархию компо-
нент RotationMovement. Данный элемент отвечает за ани-
мацию меша. В результате, при запуске игры все боксы
будут вращаться вокруг своей оси (рис. 40).
20
Infinity runner
Рисунок 38
Рисунок 39
Рисунок 40
Теперь настроим зону спауна объектов. Перейдем
в BP_FloorTile и добавим еще один компонент Box Col-
lision, который сразу переименуем в BoxArea (рис. 41).
21
Урок 10
Рисунок 41
Разместим его в центре платформы и поменяем его
размеры, чтобы плоскость зоны спауна заняла почти всю
площадь дороги (рис. 42).
Рисунок 42
Далее создаем функцию SpawnBoxes (рис. 43).
Рисунок 43
22
Infinity runner
Рисунок 44
Чтобы новые коробки спаунились в случайном ме-
сте на дороге, создадим следующий скрипт. Подключим
компонент Box Area к целевым нодам Relative Location
и Box Extent, которые необходимо соединить с помощью
функции Random Point in Bounding Box. Готовый скрипт
подключим в строку Relative Transform (рис. 45).
Рисунок 45
Рисунок 46
23
Урок 10
Рисунок 47
В результате, если несколько раз запустить симуля-
цию скрипта, ящики будут случайным образом спаунить-
ся на плоскости.
Чтобы персонаж поднимал ящики в момент столкно-
вения, добавим в его блупринт новую переменную Total-
Boxes типа Integer (рис. 48).
Рисунок 48
После это создадим функцию AddBox (рис. 49).
24
Infinity runner
Рисунок 49
Подключим к ней ноду Total Boxes. При этом коли-
чество собранных ящиков должно постоянно увеличи-
ваться на единицу. Скрипт для решения подобной зада-
чи показан на рисунке 50.
Рисунок 50
Чтобы новая функция заработала, необходимо со-
здать ивент On Component Begin Overlap в блупринте
ящика (рис. 51).
Рисунок 51
25
Урок 10
Рисунок 52
В конце скрипта добавим ноду DestroyActor, которая
будет удалять собранные ящики из вьюпорта. Дополни-
тельно в игру можно добавить звуковой эффект, кото-
рый будет проигрываться в момент, когда персонаж под-
берет объект. Для этого достаточно добавить ноду Play
Sound at Loction и выбрать подходящий звук из библио-
теки (рис. 53).
Рисунок 53
Теперь давайте визуализируем счетчик собранных
предметов. Для этого создадим новую папку и добавим
в нее блупринт виджета. Переименуем его в RunHUD
(рис. 54).
26
Infinity runner
Рисунок 54
Создадим в данном блупринте иерархию, как на ри-
сунке 55. Разместим все элементы виджета в левом верх-
нем углу вьюпорта.
Рисунок 55
Количество собранных ящиков должно оперативно
меняться. Давайте создадим логическую связь соответ-
ствующего числового виджета с действиями персонажа.
Для этого выделим его, перейдем к панели настроек —
блок Content => Bind => Create Binding (рис. 56).
Рисунок 56
27
Урок 10
Рисунок 57
Последний шаг — вывести счетчик на экран. Для это-
го вернемся в блупринт GameMode и подключим к ивен-
ту BeginPlay две ноды: Create Widget с классом RunHUD
и Add to Viewport (рис. 58).
Рисунок 58
Рисунок 59
28
Infinity runner
Рисунок 60
Трансформируем рампу так, чтобы ее площадь совпа-
дала с площадью трека, и разместим в конце пути (рис. 61).
Рисунок 61
29
Урок 10
Рисунок 62
После этого вернемся в блупринт GameMode, к функ-
ции AddFloorTile. Подключим к ноде SpawnActor новый
класс объектов — переменную массива FloorTiles. Что-
бы участки дороги выбирались случайным образом из
списка существующих, дополним скрипт нодой Random
Integer in Range (рис. 63).
Рисунок 63
30
Infinity runner
Рисунок 64
При этом на панели справа появится список элемен-
тов массива Floor Tiles. Чтобы добавить новый пункт, на-
жимаем на знак «+». После этого достаточно подключить
в массив соответствующий блупринт (рис. 65).
Рисунок 65
Давайте создадим еще один дочерний блупринт BP_
FloorTile (рис. 66).
Рисунок 66
31
Урок 10
Рисунок 67
Так как массив уже создан, достаточно добавить в него
еще один пункт и подключить соответствующий блупринт.
При этом следует обратить внимание на то, что количество
элементов массива не ограничено. Создавая новые участ
ки пути, и наполняя их необычными объектами, можно
сгенерировать действительно интересную трассу (рис. 68).
Рисунок 68
32
Infinity runner
Рисунок 69
Теперь давайте рассмотрим несколько примеров класс-
ных мобильных игр, которые могут достойно предста-
вить игрокам жанр Infinity runner:
■■ Shred it! (рис. 70);
Рисунок 70
33
Урок 10
Рисунок 71
■■ Amazing Runner (рис. 72).
Рисунок 72
34
Infinity runner
35
Урок 10
Infinity runner