- [Видео] Контейнеры Map в Unreal Engine Blueprint
- Что такое Map
- Как создать переменную в Blueprint с контейнерным типом Map
- Ручное создание Map
- Динамическое создание Map через Make Map
- Способы работы с Map
- Перебор всех пар через цикл For Each Loop (Map)
- Использование встроенных Blueprint‑функций для работы с Map
- Работа с Map через массивы
- Практика в Unreal Engine
- Вывод значений «Key → Value» в Map (используя цикл For Each для Map)
- Перебор Map в старых версиях Unreal Engine с использованием функций Keys + For Each (Array)
- Выбор конкретной пары «Key → Value» контейнера Map (функция Find)
- Добавление новой пары «Key → Value» в Map (функция Add)
- Ограничение количества добавляемых пар «Key → Value» в Map (функция Length)
- Удаление пар «Key → Value» в Map (функция Remove)
- Полная очистка Map (функция Clear)
- Краткий итог статьи: Unreal Engine Map
Друзья, приветствую, с Вами Будуев Антон. В данной статье мы поговорим о том, что такое Map в Unreal Engine Blueprint (UE4, UE5). Разберём что такое вообще Map, его отличие от массивов (Array), как создавать Map вручную и динамически, способы работы с Map, функции для работы с Map, ну а также, закрепим всю работу с Map на практике, разбирая простую, но показательную и понятную всем игровую механику через образ инвентарь игрока.
Также рекомендую скачать мою бесплатную книгу по Blueprint для Unreal Engine.
Основная цель книги — дать общий, целостный и понятный обзор системы Blueprint. Книга предлагает взгляд с высоты «птичьего полёта» — ясную и чёткую карту игрового мира Unreal Engine, которая поможет увидеть ключевые взаимосвязи и понять, как устроена система визуального скриптинга.
Зарегистрироваться в ЛК и скачать книгу [Blueprints. Взгляд с высоты «птичьего полёта»]
[Видео] Контейнеры Map в Unreal Engine Blueprint
Ссылка из видео: Книга по Blueprint для Unreal Engine
Текущая статья является логическим продолжением статьи и видеоурока, в котором мы обсуждали массивы (Array) в Unreal Engine Blueprint. Коротко напомню ключевые моменты.
В Unreal Engine логика работы строится вокруг событий. Когда движок вызывает определённые события, мы реагируем на них с помощью Blueprint-скриптов. Чтобы между этими событиями сохранять состояние объектов, используются переменные. Переменная — это сущность, способная хранить некоторое значение, которое затем можно изменять прямо в ходе игры.
Однако по умолчанию обычная переменная в Blueprint хранит только одно значение: одно число, одну строку, один текст и т. д.

Возникает вопрос — что делать, если нам нужно работать с набором значений? Например, необходимо создать инвентарь, куда игрок будет добавлять множество объектов, удалять их, сортировать и изменять.
Создавать отдельные переменные под каждую инвентарную вещь невозможно, так как переменные создаются заранее в Blueprint-классе и не могут динамически появляться в процессе игры. Поэтому нужен механизм, позволяющий в рамках одной заранее созданной переменной сохранять не одно значение, а множество.
Таким механизмом в Blueprints являются контейнерные типы переменных. По умолчанию, как я уже говорил выше, переменная имеет тип контейнера Single — то есть одиночный. Но этот тип контейнера можно изменить на Array, Set или Map.

В таком случае внутри одной переменной уже будет храниться не одно, а множество значений. Собственно, тип контейнера Array мы уже изучали в прошлой статье (видео). Кратко напомню основные моменты по массивам.
Массив — это контейнерный тип переменной, который позволяет хранить список однотипных элементов, где элементы массива:
- имеют строго определённый порядок;
- индексируются, начиная с нуля (первый элемент имеет индекс 0, второй — 1 и т. д.);
- также элементы в массиве могут повторяться.
Например, массив типа String может содержать такой инвентарь: [«bread», «water», «apple», «apple»].

Используя только массивы, уже можно создать самый простой инвентарь, в котором, по сравнению с обычными Single-переменными, мы получаем возможность динамически во время игры:
- добавлять новые элементы,
- удалять элементы,
- сортировать их,
- перебирать и подсчитывать повторения.
Однако для создания инвентаря такой подход не всегда удобен. Массивы не позволяют хранить для элементов дополнительную информацию — они содержат лишь упорядоченный список самих значений. Например, чтобы узнать количество определённого предмета (скажем, яблок), придётся каждый раз перебирать весь массив и считать повторы.
Массивы хорошо подходят для хранения нумерованных списков объектов, но неудобны, когда нужно связывать хранимый объект с дополнительными данными, например, такими как количество.
Для решения этой задачи в Unreal Engine существует другой тип контейнера переменных, который мы и рассмотрим в текущем статье — Map.
Что такое Map
Map — или по-русски карта (иногда также называют словарь) — это контейнерный тип переменной, который, в отличие от массива, позволяет хранить не просто список однотипных элементов, а список пар вида «Key → Value» (ключ → значение).

Если массив хранит нумерованный список без дополнительной информации, характеризующей элементы этого списка, то Map позволяет хранить список в виде ключей, при этом для каждого ключа можно сохранить дополнительную информацию, то есть значение, связанное с этим ключом.
В Map:
- все ключи (Key) должны быть строго одного типа данных (кроме типов Boolean, Text и Rotator — эти типы ключи не поддерживают);
- все ключи уникальны — повторяющихся быть не может;
- все значения (Value) также должны быть одного типа данных, но при этом могут повторяться и быть любого допустимого типа.
В качестве примера можно рассмотреть переменную InventoryMap с типом контейнера Map.

Где:
- ключи — это строки (String), например: «bread», «water», «apple»;
- значения — целые числа (Integer), обозначающие количество предметов.
Такую контейнерную переменную можно использовать как простой инвентарь, хранящий элементы инвентаря игрока (то есть ключи) и количество каждого элемента (значения).
Таким образом, InventoryMap остаётся одной переменной, заранее созданной в Blueprint-классе, но при этом во время игры может динамически добавлять, изменять и удалять содержимое внутри себя (внутри инвентаря) — то есть ключи и связанные с ними значения.
Как создать переменную в Blueprint с контейнерным типом Map
Ручное создание Map
Поскольку Map — это обычная переменная с особым типом контейнера, её создание происходит следующим образом.
- Создаём переменную. Называем её, например, InventoryMap.
- Во вкладке Details рядом с выбором типа данных выбираем тип контейнера → Map.
- Указываем тип данных для ключей (Key), например String, и для значений (Value), например тип данных Integer.
- Далее компилируем Blueprint.
- После компиляции во вкладке Default Value можно добавить пары «ключ–значение» с помощью кнопки «+».

Важно: все ключи в Map должны быть уникальными. В текущем случае попытка добавить повторяющийся ключ с пустым значением приведёт к ошибке. Поэтому сначала определяем первую пару «bread» → 2, затем создаём вторую пару «water» → 2 и третью — «knife» → 1.
После этого Map можно переносить в Event Graph и использовать как любую другую переменную.

Динамическое создание Map через Make Map
Map можно создавать не только вручную, но и динамически — с помощью функции Make Map и уже существующих переменных, хранящих ключи и значения.
Например, создадим две одиночные (Single) переменные:
- Pickup, типа String → со значением «juice»;
- Amount, типа Integer → со значением 1.
Передадим эти переменные в функцию Make Map:
- переменную Pickup в параметр Key (ключ),
- переменную Amount в параметр Value.
В результате функция Make Map возвращает Map, который можно сохранить в виде переменной класса через Promote to Variable.

Для добавления новых пар используется кнопка Add Pin, позволяющая динамически расширять Map.
Такой способ создания Map полезен, когда нужно создавать его во время выполнения игры, например:
- по событию Begin Play — для инициализации инвентаря;
- при получении данных из других классов или динамически формируемых переменных;
- при создании Map из заранее подготовленных значений.
Способы работы с Map
После создания Map возникает вопрос: как с ним работать на практике? В Unreal Engine есть три основных способа работы с Map.
Перебор всех пар через цикл For Each Loop (Map)
Первый способ — перебор всех пар в Map с помощью цикла For Each Loop (Map).

Для этого получаем ссылку на переменную Map, например InventoryMap, и вызываем для неё цикл For Each.
В результате цикл перебирает все пары «Key → Value» и на каждой итерации предоставляет:
- Key — ключ текущей пары;
- Value — значение текущей пары;
- Loop Body — выход для выполнения пользовательской логики при обработке пары «Key → Value».
После завершения цикла выполняется выход Completed.
Также, дополнительно, через вход Break можно досрочно остановить цикл, например, если нужный ключ найден — чтобы не перебирать оставшиеся элементы.
Примечание: специализированный цикл For Each Loop (Map) доступен в последних версиях Unreal Engine (например, в UE 5.6, на которой пишется данная статья). В более старых версиях такого узла нет, однако перебор Map в цикле также возможен, просто реализуется иначе. Как именно — рассмотрим далее на практике.
Использование встроенных Blueprint‑функций для работы с Map
Unreal Engine предоставляет небольшой набор Blueprint-функций для работы с Map (все они находятся в разделе Utilities → Map). Рассмотрим чуть подробнее данные функции.

- Add — добавляет новую пару «Key → Value». Если ключ уже существует в Map, пара не добавляется, а вместо этого новое значение Value заменяет старое. Таким образом соблюдается одно из свойств Map — уникальность ключей.
- Remove — удаляет указанный ключ и связанное с ним значение.
- Clear — полностью очищает Map от всех пар «Key → Value».

- Contains — проверяет, существует ли указанный ключ. Возвращает True, если ключ найден, иначе False.
- Find — возвращает значение по ключу. Если ключ найден — выдаёт соответствующее значение (Value) и True; если нет — возвращает дефолтное значение (например, 0 для Integer) и False.

- Get Key Value by Index — возвращает копию пары «Key → Value» по её индексу. При этом Map не гарантирует соответствия индексов порядку добавления пар в Map, но каждая пара всё же имеет свой индекс: 0, 1, 2, …
- Get Last Index — возвращает индекс последней пары. Например, для Map из трёх пар последний индекс будет 2 (так как нумерация начинается с 0).

- Is Empty — проверяет, пуст ли Map. Возвращает True, если пар нет.
- Is Not Empty — противоположна предыдущей: возвращает True, если в Map есть хотя бы одна пара.

- Length — возвращает количество пар в Map (например, 3 для трёх пар).

- Keys — возвращает массив всех ключей (Key).
- Values — возвращает массив всех значений (Value).
Работа с Map через массивы
Третий способ работы с Map — разделение его на два массива при помощи функций Keys и Values.

Разделив таким образом Map на массивы, можно применять к получившимся данным весь набор функций, доступных для массивов, которые недоступны напрямую при работе с Map. Такой подход позволяет значительно расширить возможности обработки данных, используя большой инструментарий функций для массивов, о которых подробно рассказывалось в предыдущем уроке.
Практика в Unreal Engine
Давайте перейдём к практике и разберём работу с Map в Unreal Engine на примере простого образного инвентаря.
Реальный инвентарь в игре — это отдельная большая тема, выходящая за рамки текущей статьи. Наша цель — понять, как работать с Map. Для этого возьмём максимально простой и наглядный пример работы с образным инвентарем:
- ранее мы создали Map с именем InventoryMap;
- данный Map уже содержит три элемента инвентаря, каждый со своим количеством.
Таким образом, у нас есть базовый инвентарь игрока, созданный через Map, в котором три предмета с определённым количеством.

Вывод значений «Key → Value» в Map (используя цикл For Each для Map)
Давайте выведем содержимое инвентаря на экран игрока. Обычно в играх инвентарь открывается по клавише «I», поэтому сделаем то же самое.
Создадим событие на клавишу «I». Для этого в Event Graph выберем событие Input Key, а во вкладке Details назначим клавишу «I».

Как же вывести Map на экран? Самая простая функция для вывода отладочной информации — Print String, которая выводит текстовую строку на экран.
Однако Print String работает только с одной строкой, а Map содержит несколько пар «Key → Value». Просто передать весь Map в Print String нельзя. Решение: перебрать все пары Map циклом For Each и на каждой итерации выводить ключ и значение по отдельности.
Возьмем наш InventoryMap и вызовем из него цикл For Each Loop (Map), на каждой итерации которого нам будут доступны отдельные значения Key и Value. Подключим к Loop Body функцию Print String и для начала в качестве строки для вывода подадим просто ключ (Key).
В результате:
- на первой итерации цикла функция Print String выведет строку «bread»,
- на второй — «water»,
- на третьей — «knife».
Таким образом, цикл выполнится три раза — по количеству пар в Map.
Проверим работу скрипта в игре:
Запускаем игру и нажимаем клавишу «I». На экран выводятся три строки — по одной для каждой пары Map:
- «knife»,
- «water»,
- «bread».
Цикл отработал три итерации, и Print String корректно вывел ключи Map.

Такой подход работает не только с ключами, но и с их значениями. То есть, если дополнительно нужно вывести количество каждого предмета, можно воспользоваться конкатенацией строк с помощью функции Append. В качестве первой строки укажем ключ (Key), во второй — строку « = », а в третьей — значение (Value). При этом тип Integer движок автоматически преобразует в String.
Проверим всё в игре: запускаем и нажимаем клавишу «I» — на экран выводится инвентарь из трёх строк, где отображаются и названия предметов, и их количество.

Перебор Map в старых версиях Unreal Engine с использованием функций Keys + For Each (Array)
Как уже упоминалось, специализированный цикл For Each Loop (Map) доступен только в новых версиях Unreal Engine (в нашем случае — в версии 5.6). А как быть в более ранних версиях, где такого цикла нет?
Решение — использовать перебор через массивы.
Ранее мы разбирали, что Map имеет функцию Keys, которая возвращает массив всех ключей. Так как это обычный массив, мы можем использовать стандартный цикл For Each Loop для массивов, доступный во всех версиях Unreal Engine. Данный цикл перебирает все элементы массива и на каждой итерации предоставляет доступ к конкретному элементу.
Итак, возьмём нашу переменную инвентаря InventoryMap и вызовем для неё функцию Keys, чтобы получить массив всех ключей Map. Далее подключим возвращаемый массив к стандартному циклу For Each Loop. На каждой итерации цикла используем Print String для вывода текущего элемента на экран (то есть ключа из нашего Map).
Проверим работу скрипта в игре: запускаем игру, нажимаем клавишу «I». В результате на экран выводятся все ключи Map:
- «knife»,
- «water»,
- «bread».

А как вывести не только ключи, но и значения предметов инвентаря — то есть их количество?
Для этого воспользуемся встроенной функцией Find, которая ищет указанный ключ в Map и, если ключ найден, возвращает связанное с ним значение (Value).
В нашем случае цикл For Each Loop перебирает массив всех ключей, полученный функцией Keys. На каждой итерации мы получаем текущий ключ, который подаём в функцию Find, передав ей саму переменную Map. Так как все ключи берутся напрямую из Map, функция Find всегда найдёт соответствующее значение для каждого ключа.
Далее формируем строку для вывода. Для этого используем функцию Append, чтобы объединить:
- ключ (Key);
- строку « = »;
- и значение (Value), возвращаемое функцией Find.
Результирующую строку передаём в Print String.
Проверим работу скрипта в игре. Запускаем игру, нажимаем клавишу «I». На экран выводится инвентарь игрока с указанием количества каждого предмета.

Таким образом, даже в старых версиях Unreal Engine можно перебрать Map через функцию Keys и цикл For Each Loop для массивов.
Выбор конкретной пары «Key → Value» контейнера Map (функция Find)
Мы уже научились выводить на экран все элементы инвентаря, но во многих играх требуется не просто показать весь список, а дать возможность выбрать конкретный элемент и узнать его количество.
Как это работает в обычной игре: инвентарь обычно вызывается клавишей, например «I», по нажатию на которую игроку показывается меню инвентаря. Инвентарь может состоять из нескольких вкладок, где сам инвентарь представлен общим массивом, а каждая вкладка представляет собой внутренний массив слотов, и в каждом слоте может находиться конкретный предмет.
В шутерах или RPG персонаж также может иметь общий инвентарь, представленный в виде общего массива, например Inventory, который внутри себя содержит дочерние массивы:
- массив «рюкзака», содержащий слоты для предметов;
- массив, представляющий, например, «штаны с карманами», где каждый карман — это отдельный слот массива.

Создание полноценной системы инвентаря — задача достаточно сложная, и подход зависит от конкретной реализации. Но если говорить об общей архитектуре, то базис обычно такой: каждый слот может хранить какую-то информацию о предмете инвентаря — например, начиная от его индекса (0, 1, 2) или названия («bread», «water») до других характеристик, описывающих этот предмет. Всё это уже определяется программистом при создании инвентаря.
Когда игрок выбирает конкретный слот и кликает по нему мышкой, слот может отправить во внутреннюю логику инвентаря:
- индекс, под которым он находится в массиве,
- название предмета,
- или любую другую связанную информацию.
Попробуем реализовать похожий принцип в нашей практике.
Создадим переменную SelectSlot типа String. Она будет хранить имя выбранного элемента, например «water».

Предположим, что при нажатии клавиши «2» мы хотим выбрать второй элемент инвентаря — воду («water»). И, следуя логике работы инвентарных систем, при нажатии клавиши «2» выбранный слот передаёт информацию в код через переменную SelectSlot.
Теперь получим количество выбранного элемента, имя которого хранится в SelectSlot:
- Обращаемся к нашему Map (InventoryMap).
- Вызываем функцию Find и передаём в неё ключ из переменной SelectSlot.
В итоге Find вернёт значение (Value) — то есть количество выбранного предмета.
Далее выведем результат на экран. С помощью Append формируем строку. Передаём в неё три части:
- Ключ из переменной SelectSlot.
- Строку « = »,
- Значение, возвращаемое функцией Find для заданного ключа.
Проверяем всё в игре. Нажимаем «I» — выводится весь инвентарь; нажимаем клавишу «2» — на экране появляется выбранный элемент и его количество: «water»: 2 бутылки.

Добавление новой пары «Key → Value» в Map (функция Add)
Рассмотрим следующую ситуацию с инвентарём. Например, мы хотим добавить новый элемент — то есть положить предмет в инвентарь. Для этого нужно добавить новую пару в наш Map или обновить значение существующей.
В качестве примера добавление будем выполнять по клавише «F»: игрок взаимодействует с предметами на игровом уровне и при нажатии «F» кладёт предмет себе в инвентарь. В нашем случае по нажатию на «F» необходимо добавить новую пару в Map или же обновить существующую.
Мы уже обсуждали, что для добавления новой пары в Map используется функция Add. Она добавляет в Map новую пару «Key → Value», но делает это с учётом ограничения: все ключи в Map должны быть уникальными.
Механика следующая:
- если добавляемый ключ уже существует в Map, функция Add не будет создавать новую пару, а просто обновит значение Value для текущего ключа;
- если ключ отсутствует, Add создаст новую пару «Key → Value».
У нас с вами уже есть переменная типа String с именем Pickup, в которой хранится значение «juice». Добавим этот предмет в инвентарь: передадим в функцию Add новый ключ (Pickup) и зададим значение (Value), например — 1 (то есть поднимается одна банка сока). В результате функция Add добавит в Map пару «juice» → 1.

Но бывают ситуации, когда поднимаемый предмет уже присутствует в инвентаре. Например, если переменная Pickup будет хранить в качестве поднимаемого предмета значение «water».

Функция Add также проверит наличие ключа «water» в Map и обнаружит, что он уже существует. В таком случае Add не добавит новый ключ, а просто обновит значение Value. Если раньше там были две банки воды, а игрок снова подберет воду, простое обновление в Add заменит 2 на 2 — количество не изменится.
Чтобы значение добавлялось, а не заменялось, действуем так:
- Вызываем функцию Find, чтобы получить текущее количество предмета в Map.
- Прибавляем к найденному количеству число подобранных предметов (в нашем случае 1).
- Передаём полученную сумму в функцию Add.
Тогда, если «water» было в количестве 2, а игрок подберет ещё одну единицу, итоговая сумма составит 3. Именно это обновлённое значение сохранится в Map. После этого можно вывести сообщение с помощью Print String, например: «В инвентарь добавлен новый предмет».
Проверим работу скрипта:
- Запускаем игру.
- Нажимаем «I» — в инвентаре 2 банки воды.
- Нажимаем «F» — подбираем воду.
- Нажимаем «I» снова — теперь в инвентаре 3 банки воды.

Изменим ситуацию. Пусть поднимаемый предмет (Pickup) — это сок «juice». Как сработает код в этом случае?

Функция Find попытается найти «juice» в Map, но не найдёт, так как такого ключа ещё нет. В этом случае она возвратит False и значение по умолчанию для типа Integer, равное 0. К этому значению мы прибавим количество подобранного предмета (в количестве 1) и передадим результат в функцию Add. Так как ключ «juice» отсутствует, Add создаст новую пару «juice» → 1. В итоге наш Map получит четвёртую пару.
Проверим работу скрипта:
- Запускаем игру.
- Нажимаем «I» — в инвентаре три предмета (три слота).
- Нажимаем «F» — подбираем сок.
- Нажимаем «I» снова — появился четвёртый слот: сок, в количестве — 1 банка.
- Повторяем подбор сока несколько раз.
- Нажимаем «I» — и видим, что сок теперь в количестве пяти банок.

Ограничение количества добавляемых пар «Key → Value» в Map (функция Length)
Хорошо, теперь давайте рассмотрим ситуацию, когда нужно ограничить количество слотов в инвентаре.
Допустим, сейчас в инвентаре три слота, и мы хотим сделать так, чтобы максимум одновременно можно было использовать только три слота. Для этого перед добавлением новой пары сначала необходимо узнать текущее количество пар в Map.
Используем функцию Length, которая возвращает количество пар в Map (количество ключей). Это количество нужно сравнить с максимально допустимым числом слотов. Для этого создадим переменную MaxSlotInventory типа Integer и присвоим ей значение 3.

Перед добавлением новой пары в Map проверим, меньше ли текущее количество слотов максимального значения. Если условие выполняется, только тогда можно добавлять новую пару. Для этого используем ветвление через Branch, а весь код добавления новой пары выполняем по ветке True. Если условие не выполняется, срабатывает ветка False, и в этом случае можно вывести через Print String, что свободных слотов в инвентаре нет.
Например, если в Map сейчас три пары, функция Length вернёт 3, мы сравниваем 3 с максимальным значением 3 и видим, что условие «меньше» не выполняется. Сработает ветка False, и при попытке добавить новый элемент, например «juice», выведется сообщение, что свободных слотов нет.
Проверим это в игре:
- Запускаем игру.
- Нажимаем «I» — видим, что у нас в инвентаре занято три слота.
- Нажимаем «F» — выходит сообщение, что свободных слотов в инвентаре нет, то есть мы добавить новый слот не можем.

Давайте увеличим максимально допустимое количество слотов до 4 и затем опять попробуем поднять сок в игре.

- Нажимаем «I» — у нас три слота.
- Нажимаем «F» — вышло сообщение «в инвентарь добавлен новый предмет».
- Нажимаем «I» — видим, действительно, сок был добавлен.
Вроде бы всё работает, но нет. На самом деле при таком коде у нас возникает следующая проблема. Максимальное количество слотов сейчас установлено на 4, и в инвентаре уже все 4 слота заняты, так как мы подняли «juice». Если попытаться добавить ещё одну банку сока, она не добавится, потому что свободных слотов нет. Но это неправильно, потому что слот с соком уже существует, и мы должны просто увеличить его количество, а не создавать новый слот.
Чтобы это исправить, перед проверкой количества свободных слотов необходимо сначала с помощью функции Find проверить, есть ли поднимаемый элемент в инвентаре. Если такой ключ уже есть, нужно обновить его количество без проверки свободного слота. Если же ключ не будет найден, то только тогда проверять, можно ли добавить новый ключ с учётом максимального числа слотов.
Таким образом, проверка через Find позволяет сначала обновлять количество уже существующих предметов, а проверка Length и MaxSlotInventory отвечает только за возможность добавления новых ключей в Map.
В игре это будет выглядеть так:
- Нажимаем «I» — у нас в инвентаре три элемента.
- Поднимаем сок — теперь в инвентаре стало четыре элемента, добавился сок в количестве одной банки.
- Далее мы снова можем поднять сок — в текущем варианте всё в порядке, сок добавляется и его количество растёт.

Удаление пар «Key → Value» в Map (функция Remove)
Давайте рассмотрим ситуацию, когда мы хотим воспользоваться каким-то предметом из инвентаря. Например, хотим использовать воду. Для этого создадим событие на клавишу «E», чтобы при её нажатии игрок мог использовать выбранный элемент инвентаря.
Мы уже знаем, как выбирать элемент: ранее мы организовывали этот процесс через клавишу «2», когда выбирали слот, используя переменную SelectSlot, и получали соответствующее значение из Map с помощью функции Find.
Итак, у нас есть переменная SelectSlot, которая хранит выбранный слот инвентаря, в нашем случае — воду. Вызываем функцию Find для InventoryMap, подавая в неё SelectSlot, чтобы функция Find нашла соответствующий ключ в Map и вернула значение, то есть количество предмета.
Далее вычтем из этого значения количество, которое хотим использовать, например одну единицу за раз. После вычитания необходимо проверить, больше ли остаток нуля. Если остаток положительный, значит, у нас ещё есть этот предмет, и его новое количество нужно обновить в Map. Для этого используем функцию Add, которая перезапишет значение ключа, если ключ уже существует. В нашем случае ключ «water» уже есть в Map, и функция Add просто обновит значение с 2 до 1.
Если же остаток равен нулю или стал меньше нуля, обновлять значение через Add не нужно. В этом случае мы просто удалим пару «Key → Value» из Map. Для этого воспользуемся функцией Remove, которая удаляет указанный ключ из Map, в нашем случае — SelectSlot и соответствующее ему значение. Чтобы наглядно видеть, что происходит, добавим Print String, где укажем, что предмет использован, а если же остаток предмета равен 0, то в Print String выведем сообщение, что выбранный предмет инвентаря закончился.
Таким образом, логика работы выглядит следующим образом. Функция Find находит ключ в Map и возвращает соответствующее текущее значение Value. Из этого значения вычитается количество, которое мы хотим использовать. Если остаток положительный, функция Add обновляет значение в Map. Если остаток равен нулю, ключ и его значение удаляются из Map через функцию Remove.
Проверим данный скрипт в игре:
- Нажимаем «I» — у нас в инвентаре две банки воды.
- Нажимаем «E» — используем предмет «water».
- Нажимаем «I» — в инвентаре теперь осталась одна банка воды.
- Нажимаем ещё раз «E» — то есть используем воду, выходит сообщение, что предмет инвентаря «water» закончился.
- Нажимаем «I» ещё раз — смотрим в инвентарь: воды больше нет, пару с ключом «water» мы удалили из Map.

Полная очистка Map (функция Clear)
И последнее, что мы сейчас протестируем на практике, — это полную очистку Map.
Давайте воссоздадим ситуацию, будто игрок потерял свой рюкзак. Сделаем так, чтобы рюкзак «терялся» при нажатии на клавишу «P».
Возьмём наш инвентарь InventoryMap и вызовем у него функцию Clear. Эта функция полностью очищает Map, удаляя все пары «Key → Value». После выполнения данной операции выведем сообщение о том, что рюкзак утерян.

Теперь проверим это в игре:
- Запускаем игру
- Нажимаем «I» — инвентарь есть.
- Нажимаем «P» — выводится сообщение «рюкзак утерян».
- Снова нажимаем «I» — ничего не появляется, потому что Map пустой, инвентарь очищен.
- Затем нажимаем «F», чтобы подобрать предмет. Появляется сообщение, что в инвентарь добавлен новый предмет.
- Нажимаем «I» — видим, что подняли одну банку сока.
- Ещё несколько раз нажимаем «F», поднимаем сок.
- При проверке через «I» видим, что в инвентаре уже шесть банок сока.
- Снова нажимаем «P», теряем рюкзак.
- Нажимаем «I» — и инвентарь снова пустой, ничего не выводится.
Таким образом, полная очистка Map через функцию Clear работает корректно, и сценарий потери рюкзака реализован полностью.
Краткий итог статьи: Unreal Engine Map
Итак, в данной статье мы разобрали, что такое Map в Unreal Engine Blueprint. Напомню, это тип контейнера переменной или, иначе говоря, структура данных, которая хранит пары «Key → Value», где каждый ключ уникален, а значения могут повторяться. Важно, что все ключи (Key) должны быть строго одного типа (за исключением типов Boolean, Text и Rotator — эти типы данных ключи не поддерживают), и все значения (Value) также должны иметь единый тип данных, при этом сам тип значения может быть любым допустимым типом в Blueprint.
Контейнер Map особенно удобен при создании простых систем инвентаря, а также во всех ситуациях, где необходимо хранить не просто список элементов, но и некоторую связанную информацию для каждого элемента. И если говорить точнее, Map позволяет хранить дополнительные данные, привязанные к конкретным ключам, что делает его идеальным инструментом для подобных задач.
Напоминаю про мою бесплатную книгу по Blueprint для Unreal Engine.
Основная цель книги — дать общий, целостный и понятный обзор системы Blueprint. Книга предлагает взгляд с высоты «птичьего полёта» — ясную и чёткую карту игрового мира Unreal Engine, которая поможет увидеть ключевые взаимосвязи и понять, как устроена система визуального скриптинга.
Зарегистрироваться в ЛК и скачать книгу [Blueprints. Взгляд с высоты «птичьего полёта»]










