Я отвечу на каждое требование, но в порядке, отличном от указанного в вопросе. Для третьего требования было бы лучше использовать класс PlayerController
вместо класса PlayerState
, потому что контроллер игрока для клиента существует только на сервере и на клиенте-владельце, поэтому любая информация, относящаяся к контроллеру игрока, только реплицируется. от сервера к клиенту-владельцу. С другой стороны, состояние игрока для клиента существует на сервере и всех клиентах, поэтому любая информация, относящаяся к состоянию игрока, будет реплицирована с сервера на всех клиентов, а это означает, что все игроки имеют доступ к своим собственным и всем. состояние игрока else.
Для первого требования было бы лучше использовать класс PlayerState
вместо класса PlayerController
. Обратите внимание, что при изменении уровня состояние игрока и его контроллер уничтожаются и воссоздаются. Однако с помощью состояния проигрывателя вы можете переопределить метод CopyProperties
, который отвечает за копирование определенной c информации из старого экземпляра в новый экземпляр состояния проигрывателя. Кроме того, это будет работать, только если включено плавное перемещение. Подробнее о бесшовном путешествии можно прочитать здесь . Вы также можете использовать класс GameInstance
, поскольку экземпляр игры не уничтожается ни при изменении карты, ни при уничтожении действующего актера / пешки. Но экземпляр игры имеет отношение только к клиенту, поэтому каждый клиент и даже сервер имеют свой собственный экземпляр экземпляра игры, который никому не передается.
Для второго требования экземпляры либо * Класс 1013 * или PlayerController
не уничтожается / не возрождается, когда действующий актер / пешка уничтожается / возрождается. Следовательно, любой класс будет работать для этого конкретного требования c.
В заключение, кажется, что класс PlayerState
является наиболее подходящим, потому что, как вы упомянули, при определении свойств для репликации вы можете контролировать уровень, на котором они реплицируются, когда вы переопределяете метод GetLifetimeReplicatedProps
и передаете COND_OwnerOnly
вызову функции DOREPLIFETIME_CONDITION
. Вот пример этого:
void ACustomPlayerState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME_CONDITION(ACustomPlayerState, CustomProp, COND_OwnerOnly);
}
В дополнение к этому, вы также должны переопределить метод CopyProperties
, чтобы «сохранять» специфическую c информацию при изменении карты. Вот пример из проекта ShooterGame :
void AShooterPlayerState::CopyProperties(APlayerState* PlayerState)
{
Super::CopyProperties(PlayerState);
AShooterPlayerState* ShooterPlayer = Cast<AShooterPlayerState>(PlayerState);
if (ShooterPlayer)
{
ShooterPlayer->TeamNumber = TeamNumber;
}
}
Источники для этого ответа, а также для получения дополнительной информации о концепциях многопользовательской игры в Unreal Engine: