Для отслеживания количества устранений, совершенных игроком, мы будем использовать ассоциативный массив. Ассоциативные массивы являются удобным представлением пар ключ-значение, и на разбираемом примере мы будем использовать игрока в качестве ключа, а связанный с ним уровень оружия (целочисленное значение int) — в качестве значения. Таким образом, мы сможем получать текущий уровень игрока, имея только ссылку на него. Ниже приведён пример того, как может выглядеть ассоциативный массив для игроков и уровней оружия.
Ключ | игрок 1 | игрок 2 | игрок 3 |
Значение | 1 | 2 | 2 |
Оружие в игре | Боевой пистолет L1 | Пистолет «Бретёр» L1 | Пистолет «Бретёр» L1 |
Для заполнения ассоциативных массивов игроков выполните следующие шаги:
-
Добавьте ассоциативный массив типа
[player]int
с названиемPlayerMap
в классteam_elimination_game
. В нём будут храниться ссылки на каждого игрока и соответствующие уровни оружия.team_elimination_game := class(creative_device): var PlayerMap : [player]int = map{}
-
Добавьте новый метод
PopulateTeamsAndPlayers()
в классteam_elimination_game
. Данный метод будет заполнять массивPlayerMap
и будет вызываться из блокаOnBegin()
.PopulateTeamsAndPlayers() : void= Print("Начинаю заполнение игроков")
-
В класс
team_elimination_game
добавьте новый методOnPlayerEliminated
. Он будет вызываться при каждом устранении игрока и будет определять, кто именно его устранил, путём обращения к структуреelimination_result
, переданной в качестве аргумента.OnPlayerEliminated(Result : elimination_result) : void= Print("Игрок устранён!")
-
В начале игры необходимо выполнить итерацию по списку игроков и выдать для всех оружие первого уровня. Внутри
PopulateTeamsAndPlayers
получите всех игроков с помощью методаGetPlaySpace().GetPlayers()
и сохраните их в массивAllPlayers
. Для каждого игрока получите значениеFortCharacter
и сохраните его в переменнойFortCharacter
. ВPlayerMap
присвойте счёту игрока значение 0, чтобы выдать ему первое оружие из массиваWeaponGranters
, а затем подпишите методFortCharacter.EliminatedEvent()
наOnPlayerEliminated
.AllPlayers := GetPlayspace().GetPlayers() for (Agent : AllPlayers, TeamPlayer := player[Agent], FortCharacter := TeamPlayer.GetFortCharacter[]): if(set PlayerMap[TeamPlayer] = 0, WeaponTier := PlayerMap[TeamPlayer]): Print("В PlayerMap добавлен игрок с уровнем оружия {WeaponTier}") FortCharacter.EliminatedEvent().Subscribe(OnPlayerEliminated)
-
С помощью ссылки на счёт игрока в массиве
PlayerMap
можно предоставить ему первое оружие. Внесём изменения в блокOnPlayerSpawn
, чтобы выдать игрокам первое оружие. При появлении игрока получите его уровень оружия изPlayerMap
и сохраните его в переменнойWeaponTier
, затем вызовитеGrantWeapon
, передав значениеWeaponTier
и ссылку на игрока.OnPlayerSpawn(InPlayer : agent) : void = Print("Игрок появился!") if(WeaponTier := PlayerMap[InPlayer]): GrantWeapon(option{InPlayer}, WeaponTier) Print("Появившемуся игроку выдано оружие уровня {WeaponTier}")
-
Сохраните сценарий в Visual Studio Code, скомпилируйте его и нажмите Запустить сеанс на панели инструментов UEFN, чтобы выполнить игровой тест уровня. При тестировании уровня игрок должен появиться с первым оружием из массива
WeaponGranters
. Проверьте верность поведения с помощью журнала.

Распределение команд
Мы успешно создали ассоциативный массив для игроков, теперь подумаем о том, как проверять счёт игрока. Поскольку наш сценарий автоматически повышает уровень игрока в команде с наименьшим количеством устранений, нет смысла проверять уровень оружия игроков вражеской команды. В связи с этим вы уже наверняка заметили одну проблему: в массиве PlayerMap
нет различий между игроками из разных команд.
Чтобы решить эту проблему, можно использовать ещё один ассоциативный массив. Для этого немного изменим массив PlayerMap
, добавив в него систему вложенных ассоциативных массивов. Поскольку пары «ключ-значение» в таком массиве могут относиться к любому из типов, будет логичным сделать так, чтобы ключ команды имел другой ассоциативный массив в качестве своего значения. Первый ассоциативный массив будет связывать команды (ключ) с другим ассоциативным массивом игроков этой команды (значение). Вложенный массив, в свою очередь, будет использоваться для связывания игроков (ключ) с их счётом (значение).
Теперь, получив игрока, вы сможете проверить, в какой команде он находится, при помощи GetTeam()
. Вы также сможете получить список товарищей по команде, чтобы сравнить количество устранений.
Синтаксис вложенного массива [team][player]int некоторым может показаться непонятным. В этой ситуации для упрощения понимания вы можете создать для него собственный псевдоним типа. В этом примере мы создадим для [player]int псевдоним player_map. Таким образом, для обращения к [player]int
вы сможете использовать псевдоним player_map
, а вложенный массив можно записать как [team]player_map
: то есть как ассоциативный массив, связывающий команды с ассоциативными массивами игроков.
Выполните следующие действия, чтобы адаптировать ассоциативный массив к вложенной системе массивов:
-
Перед определением класса
team_elimination_game
добавьте псевдоним для[player]int
с названиемplayer_map
.player_map := [player]int # Это псевдоним типа! team_elimination_game := class(creative_device):
-
Замените созданную ранее переменную
PlayerMap
изteam_elimination_game
на новую переменнуюTeamMap
типа[team]player_map
.# Ассоциативный массив Team Map, где ключ — это команда, а значение — ассоциативный массив # из пар «игрок» (ключ) -> «целое число» (значение) var TeamMap : [team]player_map = map{}
-
Поскольку значение
TeamMap
имеет типplayer_map
, для каждой команды необходимо инициализировать ассоциативный массив игроков, заполнить его, установить для каждого игрока значение0
, а затем присвоить этот массив игроков кTeamMap
. Измените блокPopulateTeamsAndPlayers()
, добавив в него обновлённый код.- Для каждой команды найдите игроков этой команды и сохраните их в переменной
TeamPlayers
. Инициализируйте новую переменнуюPlayerMap
типаplayer_map
для сопоставления игроков с их счётом.
PopulateTeamsAndPlayers() : void= Print("Начинаю заполнение игроков") for (Team : Teams, TeamPlayers := GetPlayspace().GetTeamCollection().GetAgents[Team]): var PlayerMap : player_map = map {}
- Для каждого игрока в
TeamPlayers
получите значениеFortCharacter
и сохраните его в переменнойFortCharacter
. ВPlayerMap
присвойте счёту игрока значение0
, чтобы выдать ему первое оружие из массиваWeaponGranters
, а затем подпишите методFortCharacter.EliminatedEvent()
наOnPlayerEliminated
.
PopulateTeamsAndPlayers() : void = Print("Начинаю заполнение игроков") for (Team : Teams, TeamPlayers := GetPlayspace().GetTeamCollection().GetAgents[Team]): var PlayerMap : player_map = map {} for (Agent : TeamPlayers, TeamPlayer := player[Agent], FortCharacter := Agent.GetFortCharacter[]): if(set PlayerMap[TeamPlayer] = 0, WeaponTier := PlayerMap[TeamPlayer]): Print("В PlayerMap добавлен игрок с уровнем оружия {WeaponTier}") FortCharacter.EliminatedEvent().Subscribe(OnPlayerEliminated)
- Наконец, установите
PlayerMap
в качестве значения текущего ключаTeam
вTeamMap
. КодPopulateTeamsAndPlayers
теперь должен выглядеть следующим образом.
PopulateTeamsAndPlayers() : void = Print("Начинаю заполнение игроков") for (Team : Teams, TeamPlayers := GetPlayspace().GetTeamCollection().GetAgents[Team]): var PlayerMap : player_map = map {} for (Agent : TeamPlayers, TeamPlayer := player[Agent], FortCharacter := Agent.GetFortCharacter[]): if(set PlayerMap[TeamPlayer] = 0, WeaponTier := PlayerMap[TeamPlayer]): Print("В PlayerMap добавлен игрок с уровнем оружия {WeaponTier}") FortCharacter.EliminatedEvent().Subscribe(OnPlayerEliminated) if(set TeamMap[Team] = PlayerMap): Print("Команда успешно добавлена в TeamMap")
- Для каждой команды найдите игроков этой команды и сохраните их в переменной
-
После создания
TeamMap
обновитеOnPlayerSpawn
таким образом, чтобы получить доступ к команде игрока с помощью методаGetTeam[]
и сохранить её в локальной переменнойPlayerTeam
. Установите значениеWeaponTier
путём получения текущего счёта игрока изTeamMap
, используяPlayerTeam
и ссылку на игрока. Обновлённый блокOnPlayerSpawn()
сейчас должен выглядеть следующим образом.OnPlayerSpawn(InPlayer : agent) : void = Print("Игрок появился!") if: PlayerTeam := GetPlayspace().GetTeamCollection().GetTeam[InPlayer] WeaponTier:int := TeamMap[PlayerTeam][InPlayer] then: GrantWeapon(option{InPlayer}, WeaponTier) Print("Появившемуся игроку выдано оружие уровня {WeaponTier}")
Сохраните сценарий в Visual Studio Code, скомпилируйте его и нажмите Запустить сеанс на панели инструментов UEFN, чтобы выполнить игровой тест уровня. При тестировании уровня игрок снова должен появиться с первым оружием из массива WeaponGranters
. Убедитесь, что этот так, проверив журнал.

Что дальше
Дальше мы разберём, как выдавать игрокам оружие, когда они зарабатывают очки за устранение.