Спроектируйте командную логику для командного мультиплеерного режима в Unreal Engine — две и более команды, отключённый дружественный огонь внутри команды, командный счёт и таблички с именами в цвет команды. Сервер должен назначать и балансировать команды; клиент никогда не должен сам решать, кто союзник, или сообщать убийства, которые сам считает валидными. Каждому клиенту нужно читать команду каждого игрока, чтобы красить таблички и проверять свой/чужой, поэтому принадлежность игрока к команде должна быть видна всем клиентам. Команда игрока должна пережить смерть и возрождение его персонажа и пережить отключение/переподключение, чтобы он вернулся на ту же сторону. Опишите, где вы храните принадлежность к команде и командный счёт, кто назначает команды, как разрешаются свой/чужой и дружественный огонь, и компромиссы вашего подхода.
Храните реплицируемый TeamId на каждом PlayerState; GameMode назначает команды на сервере. Используйте GenericTeamId для проверок свой/чужой, держите счёт команд на GameState, и пропускайте урон и цели через серверное сравнение команд.
- ✗Хранить команду на нереплицируемом или клиентском объекте, недоступном другим клиентам
- ✗Позволять клиентам решать свой/чужой вместо серверного сравнения команд
- ✗Назначать команды вне GameMode, ломая баланс и логику переподключения
- →Как бы вы обработали переподключение игрока с возвратом в его исходную команду?
- →Как бы вы реализовали командный чат и таблички с именами в цвет команды?
Ключевые классы
AGameMode— server-only: назначаетTeamId, балансирует составы, ведёт правила.AGameState— реплицируется всем: счёт команд, фаза матча, таймер раунда.APlayerState— на игрока: реплицируемыйTeamId, статистика, имя.IGenericTeamAgentInterface— стандартный интерфейс UE для запросаFGenericTeamIdу Pawn/Controller.
Модель данных
TeamId живёт на PlayerState, потому что PlayerState переживает респаун Pawn и доступен всем клиентам. GameState хранит агрегаты команд. Назначение и баланс — исключительно ответственность GameMode.
Поток данных
- Игрок подключается →
GameModeназначаетTeamId(баланс по размеру команд). TeamIdпишется наPlayerState, реплицируется всем клиентам.- Событие урона → сервер сравнивает
TeamIdинстигатора и цели; дружественный огонь блокируется по правилу. - Цель захвачена → сервер начисляет очки на
GameState. - Клиенты читают реплицированные
TeamIdи счёт для цветов табличек и таблицы очков.
Соображения по репликации
TeamId на PlayerState — Replicated, поэтому виден всем для окраски и проверок. Решения свой/чужой принимает только сервер. GameState реплицирует счёт; GameMode существует лишь на сервере и никогда не реплицируется. Командный чат фильтруется на сервере по TeamId получателей.
Настройка дизайнером
Число команд, размер, правила баланса и дружественный огонь — поля DataAsset или конфиг GameMode. Цвета команд — DataTable. Точки спавна тегируются по команде.
Компромиссы
TeamIdнаPlayerStatevs. наPawn: наPlayerStateпереживает смерть и переподключение; наPawnтеряется при респауне.GenericTeamIdUE vs. своя система: стандарт интегрирован с ИИ-восприятием, но менее гибок для сложных альянсов.