// Fill out your copyright notice in the Description page of Project Settings. #include "SurvivalPlayerState.h" #include "CharacterAppearanceComponent.h" #include "FpsPlayer.h" #include "Net/UnrealNetwork.h" void ASurvivalPlayerState::GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const { Super::GetLifetimeReplicatedProps(OutLifetimeProps); // Aucune condition : COND_OwnerOnly serait exactement le contraire de ce // qu'on veut. L'interet d'une apparence, c'est que les trois autres la // voient ; celle du proprietaire est la seule dont il pourrait se passer, // puisqu'il ne voit pas son propre corps en vue premiere personne. DOREPLIFETIME(ASurvivalPlayerState, CharacterAppearance); } void ASurvivalPlayerState::SetCharacterAppearance(const FCharacterAppearance& InAppearance) { if (!HasAuthority()) { UE_LOG(LogTemp, Warning, TEXT("ASurvivalPlayerState : SetCharacterAppearance appelee sans autorite, ignoree.")); return; } // L'apparence n'est PAS validee ici, et c'est deliberé : borner un index // demande le catalogue, que seul UCharacterAppearanceComponent connait. Or // celui-ci passe deja tout ce qu'il monte par Catalog->Sanitize(), donc un // index aberrant venu du reseau est corrige au montage, sur chaque machine. // Dupliquer la validation ici demanderait de donner le catalogue au // PlayerState pour un resultat identique -- et cette coop entre amis n'a de // toute facon aucune anti-triche a faire respecter. CharacterAppearance = InAppearance; // Un OnRep ne se declenche jamais sur la machine qui ecrit la propriete. // Chez l'hote, qui est serveur ET client local, sans cette ligne son propre // personnage resterait au visage par defaut pendant que les autres le // verraient correctement. ApplyAppearanceToPawn(); } void ASurvivalPlayerState::OnRep_CharacterAppearance() { ApplyAppearanceToPawn(); } void ASurvivalPlayerState::ApplyAppearanceToPawn() { // Le pawn peut manquer, et ce n'est pas une erreur : chez un client, le // PlayerState et le pawn arrivent par deux chemins de replication // independants, dans un ordre qu'on ne controle pas. Quand c'est le // PlayerState qui gagne, on ne fait rien -- c'est le BeginPlay du pawn qui // viendra chercher l'apparence a son tour. if (AFpsPlayer* Player = Cast(GetPawn())) { if (UCharacterAppearanceComponent* Appearance = Player->GetAppearanceComponent()) { Appearance->ApplyAppearance(CharacterAppearance); } } } void ASurvivalPlayerState::CopyProperties(APlayerState* PlayerState) { Super::CopyProperties(PlayerState); if (ASurvivalPlayerState* SurvivalState = Cast(PlayerState)) { SurvivalState->CharacterAppearance = CharacterAppearance; } }