Ue5 Oop
Ue5 Oop
Объектно ориентированное
программирование
в Unreal Engine5
В этом разделе мы познакомимся с классами в Unreal Engine 5. Для начинающих мы
подготовили небольшое введение по теме «Основы объектно ориентированного про-
граммирования», в котором очень сжато изложены базовые понятия этой концепции
разработки. Изложенный во введении материал, конечно, не сделает вас асом объ-
ектно ориентированного подхода, но все же позволит получить базовое понимание
этой философии и даст вам путеводную нить в эту занимательную область програм-
мирования. Если у вас есть опыт в ООП-разработке, вы можете пропустить вводный
текст и сразу перейти к основному материалу раздела.
12
В этой книге мы не будем вводить понятие «система», хотя с точки зрения строгости
изложения это было бы правильно. Вы можете самостоятельно ознакомиться с упомянутым
термином и современным системно-инженерным подходом к нему, воспользовавшись
работами А. И. Левенчука (начать можно с его личного блога «Лабораторный журнал»,
доступного по адресу: https://ailev.livejournal.com).
120 • ГЛАВА 4
уже стало очевидно, что разбиение большой системы на более мелкие подсистемы,
с каждой из которых можно работать независимо, сильно упрощает работу со сложным
«организмом». Такой подход в общем случае называется декомпозицией.
Если вам уже приходилось писать программный код, вы наверняка сталкивались
с алгоритмической декомпозицией (algorithmic decomposition) — процессом разде-
ления системы на части, каждая из которых отражает некоторый этап общего процес-
са. Гейм-дизайнеры используют декомпозицию, чтобы свести комплексные механики
к атомарным13. Декомпозиции окружают нас повсюду и, говоря об объектно ориенти-
рованном подходе, мы будем подразумевать объектовую декомпозицию.
Из всего вышесказанного становится понятно, что в ООП все вертится вокруг поня-
тия «объект» [object]. Объект — это произвольная сущность, для которой достаточно
легко определить границы, состояние и поведение. Каждая из этих характеристик
имеет формальное определение, но об этом мы поговорим позже, а пока что да-
вайте попробуем понять их на интуитивном уровне, рассмотрев следующий пример.
Итак, что же такое объекты? На самом деле мы каждый день взаимодействуем с ними:
ложками, чашками, ручками, ноутбуками, мылом, стиральной машиной, трамваем,
в конце концов, друзьями и коллегами (да простят авторов последние). Материаль-
ные границы всех этих сущностей позволяют нам отличать друг от друга объекты раз-
ных типов: ложки от чашек, чашки от плошек, утюги от кушаков и т. д. Отличать друг
от друга объекты одного типа (ложки от ложек, чашки от чашек, игрока от игрока) нам
помогает следующая характеристика — состояние. Например, ложка может быть алю-
миниевая или серебряная, то есть ее состояние определяется ее материалом, кроме
того, ложка может быть алюминиевая теплая или серебряная холодная, в этом случае
ее состояние выражено уже двумя характеристиками: материалом и температурой.
И конечно, объект может позволять с собой что-то делать. Да-да, именно так! Поведе-
ние — это не только делать что-то самому, это еще и страдательный залог: позволять
13
Гимельрейх С. «Игровая механика, динамика и машина состояний: Часть I» (https://gdcuffs.
com/game_mechanics_deconstruct_1/), «Игровые механики: Часть II» (https://gdcuffs.com/
game_mechanics_deconstruct_2/).
ОСНОВЫ BLUEPRINTS • 121
что-то делать с собой. Например, ложку можно помыть (и возможно, от мытья в горя-
чей воде она изменит состояние с холодной на горячую), стиральную машину можно
включить, студента можно отчислить, игровой объект активировать и т. п.
Итак, теперь мы знаем достаточно, чтобы понять суть классов. Помните однотипные
объекты: ложки, чашки, плошки? Именно их описание — обозначение типа объек-
та — и приводит нас к понятию класса: класс ложек, класс чашек, класс плошек. Оче-
видно, что все ложки примерно одинаковы и отличаются совокупностями значений
атрибутов (состоянием), все чашки тоже примерно одинаковы и тоже отличаются друг
от друга состоянием, и т. д. С любым объектом одного типа можно взаимодействовать
122 • ГЛАВА 4
14
Буч Г., Максимчук Р. А., Энгл М. У., Янг Б. Д., Коналлен Д., Хьюстон К.А.. Объектно ориентиро-
ванный анализ и проектирование с примерами приложений. М. : Вильямс, 2017.
ОСНОВЫ BLUEPRINTS • 123
книги и не пугая его обилием теории. Кроме того, полученная информация позволит
вам впоследствии легче подойти к изучению «взрослого» ООП.
Будет нелишним отметить, что среди прочего базовые принципы ООП нацелены
на поддержку повторного использования кода. Если какой-то фрагмент программы
можно вызвать повторно или же сэкономить время на написании нового кода за счет
«отсылки» к существующему, то ленивый (в данном случае это синоним рациональ-
ности) программист обязан так и сделать. Дублирование и создание плохо проду-
манных, малоразличимых между собой фрагментов кода является антипаттерном
программирования (шаблоном «так делать нельзя») под названием WET (We Enjoy
Typing). Эти же явления породили и шаблон (паттерн) DRY (Don’t Repeat Yourself).
Как правило, классы образуют иерархии, происходит это благодаря механизму насле-
дования. С точки зрения пишущего код человека наследование — это способ создать
один тип данных на основе другого типа данных, о котором мы уже все знаем (вспом-
ните определение классов и объектов) и не желаем перепечатывать один и тот же код.
Формально наследование можно охарактеризовать так:
Помните наши диаграммы классов? Знаком «-» мы обозначали закрытые члены клас-
сов, они скрыты внутри объектов, и только сами эти объекты знают о существовании
этих атрибутов и методов; знаком «+» отмечались открытые члены классов, доступные
любому вызывающему коду через объект этого типа; а вот про отметку «#» мы лишь
упомянули, что она делает члены класса защищенными. Это означает, что снаружи
объекта такой член класса не виден, но в отличие от закрытого атрибута или метода
он доступен для наследования. Если в родительском классе есть защищенные члены,
то они будут доступны всем классам-наследникам. По этой причине иногда говорят,
что наследование нарушает инкапсуляцию или что при наследовании детали реали-
зации родительского класса становятся доступными наследнику. Мы не будем углу-
бляться в разбор этого вопроса, в полном объеме он обсуждается в специальной ли-
тературе по ООП и его философии.
Итак, нам осталось разобраться только с полиморфизмом. Само название этой кон-
цепции (поли-) говорит о том, что она связана со множественностью форм, давайте
попробуем разобраться, о чем здесь идет речь. Благодаря знакомству с принципом
наследования понять суть полиморфизма будет легче. Итак, предположим, что в на-
шей иерарахии шлемов появился еще один — шлем стихий (ElementHelmet). Поми-
мо свойств простого шлема шлем стихий дополнительно характеризуется названием
ОСНОВЫ BLUEPRINTS • 127
Говорят, что между объектами существует зависимость, если один объект может
каким-либо образом воздействовать на время жизни другого объекта, например
128 • ГЛАВА 4
создавать его, удалять или даже просто «знать» о существовании этой другой сущно-
сти. Конечно, выполнения только этого условия недостаточно, существуют и другие ха-
рактеристики. Возвращаясь к концепции независимости, отметим, что время жизни
независимых объектов друг с другом никак не связано.
Отношение зависимости (dependency) в противовес независимости описывает бо-
лее общий тип отношений между классами, говоря о том, что один класс зависим
от особенностей реализации другого класса, при этом не указывая на особенности
этой зависимости.
Между классами могут существовать следующие виды отношений: ассоциация,
использование, агрегация и композиция. Последние два являются наиболее
жесткими. Давайте рассмотрим их поближе.
Отношение ассоциации (association) появляется в случае взаимного включения
классов, в таких случаях говорят, что между ними возникает двунаправленная связь.
Это означает, что объекты классов «знают» о существовании друг друга, в коде же это
знание выражается наличием ссылок соответствующих типов в полях классов. С ас-
социациями связано понятие множественности или кратности ассоциации, то есть
числа объектов, участвующих в ассоциации с каждой стороны:
Рисунок 128. Пример обозначения отношения «ассоциация» (разной кратности) между классами
ОСНОВЫ BLUEPRINTS • 129
удаление не должно коснуться игроков, так как они являются самостоятельными сущ-
ностями и должны продолжать «жить». Этот момент является главной особенностью
агрегации — она не управляет временем жизни своих составных частей, то есть це-
лое не берет на себя обязательства по уничтожению частей при завершении своего
жизненного цикла.
Вероятно, вы уже обратили внимание на то, что в рассказе об агрегации используется
то контекст классов, то объектов. Безусловно, это всего лишь легкая терминологиче-
ская вольность, так как мы все же говорим о классах, но ведь отношение агрегации
между объектами и является следствием агрегации между классами.
Если смотреть с точки зрения управления временем жизни, то совсем иначе выглядит
такой вариант агрегации как композиция (композитная агрегация, composition).
В этом случае и целое (объект-агрегат) не существует без своих частей, и его части
тоже не существуют без своего «агрегатора». Например, если в игре вы имеете дело
с домом, то при его строительстве можно выбирать разные варианты крыши, балко-
на, фасада и прочих элементов, но если вы захотите разрушить постройку, то снесете
ее целиком вместе с крышей, балконом и фасадом (на диаграмме классов UML ком-
позиция, как и агрегация, изображается стрелкой с ромбом, но в этом случае ромб
будет закрашен, отражая тем самым неразрывную связь частей и целого, см. рису-
нок 130).
1) тело;
2) камера.
Добавьте в блюпринт компонент Cube и сделайте его корнем. Далее добавьте компо-
нент Camera и установите ее немного позади и над кубиком, чтобы восприятие героя
было таким, каким оно бывает в играх от третьего лица.