一、......
1.在PlayerController类通过UGameplayStatics::GetGameState可以获得游戏状态AGameState类和子类,通过GetPlayerState可以获得APlayerState和子类
2.在GameMode类中通过GetGameState获得GameState和子类
3.在GameMode类中存在比赛状态的命名控件namespace MatchState,想添加新的比赛状态在GameMode的子类中模仿GameMode类在头文件和源文件添加方式添加
4.PlayerState中GetPlayerName函数获得的时Steam上的名字
二、添加GameState类
1.新建类
2. 代码
// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "GameFramework/GameState.h"
#include "BlasterGameState.generated.h"/*** */
UCLASS()
class BLASTER_API ABlasterGameState : public AGameState
{GENERATED_BODY()
public:virtual void GetLifetimeReplicatedProps(TArray< FLifetimeProperty >& OutLifetimeProps) const override;void UpdateTopScore(class ABlasterPlayerState* ScoringPlayer);UPROPERTY(Replicated)TArray<ABlasterPlayerState*> TopScoringPlayers;
private:float TopScore;
};
// Fill out your copyright notice in the Description page of Project Settings.#include "BlasterGameState.h"
#include "Net/UnrealNetwork.h"
#include "Blaster/PlayerState/BlasterPlayerState.h"void ABlasterGameState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{Super::GetLifetimeReplicatedProps(OutLifetimeProps);DOREPLIFETIME(ABlasterGameState, TopScoringPlayers);
}void ABlasterGameState::UpdateTopScore(ABlasterPlayerState* ScoringPlayer)
{if (TopScoringPlayers.Num() == 0){TopScoringPlayers.Add(ScoringPlayer);TopScore = ScoringPlayer->GetScore();}else if (ScoringPlayer->GetScore() == TopScore){TopScoringPlayers.AddUnique(ScoringPlayer);}else if (ScoringPlayer->GetScore() > TopScore){TopScoringPlayers.Empty();TopScoringPlayers.AddUnique(ScoringPlayer);TopScore = ScoringPlayer->GetScore();}
}
三、创建游戏结束的界面
2. 代码
// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "Announcement.generated.h"/*** */
UCLASS()
class BLASTER_API UAnnouncement : public UUserWidget
{GENERATED_BODY()
public:UPROPERTY(meta = (Bindwidget))class UTextBlock* AnnouncementText;UPROPERTY(meta = (Bindwidget))UTextBlock* InfoText;UPROPERTY(meta = (Bindwidget))UTextBlock* WarmupTime;
};
3. 在HUD类中添加新界面类的变量和函数
UPROPERTY(EditAnywhere, Category = "Announcements")TSubclassOf<UUserWidget> AnnouncementClass;UPROPERTY()class UAnnouncement* Announcement;void AddAnnouncement();
void AABasterHUD::AddAnnouncement()
{APlayerController* PlayController = GetOwningPlayerController();if (PlayController && AnnouncementClass){Announcement = CreateWidget<UAnnouncement>(PlayController, AnnouncementClass);Announcement->AddToViewport();}
}
4.在PlayerController中实现HandleCool函数中实现在界面上显示的功能
private:UPROPERTY(ReplicatedUsing = OnRep_MatchState)FName MatchState;UFUNCTION()void OnRep_MatchState();
void ABlasterPlayerController::OnMatchStateSet(FName State)
{MatchState = State;if (MatchState == MatchState::InProgress){HandleMatchHasStarted();}else if (MatchState == MatchState::Cooldown){HandleCooldown();}
}void ABlasterPlayerController::OnRep_MatchState()
{if (MatchState == MatchState::InProgress){HandleMatchHasStarted();}else if (MatchState == MatchState::Cooldown){HandleCooldown();}
}void ABlasterPlayerController::HandleMatchHasStarted()
{BlasterHUD = BlasterHUD == nullptr ? Cast<AABasterHUD>(GetHUD()) : BlasterHUD;if (BlasterHUD){BlasterHUD->AddCharacterOverlay();if (BlasterHUD->Announcement){BlasterHUD->Announcement->SetVisibility(ESlateVisibility::Hidden);}}
}void ABlasterPlayerController::HandleCooldown()
{BlasterHUD = BlasterHUD == nullptr ? Cast<AABasterHUD>(GetHUD()) : BlasterHUD;if (BlasterHUD){BlasterHUD->CharacterOverlay->RemoveFromParent();bool bHUDValid = BlasterHUD->Announcement&& BlasterHUD->Announcement->AnnouncementText&& BlasterHUD->Announcement->InfoText;if (bHUDValid){BlasterHUD->Announcement->SetVisibility(ESlateVisibility::Visible);FString AnnouncementText("New Match Starts In:");BlasterHUD->Announcement->AnnouncementText->SetText(FText::FromString(AnnouncementText));ABlasterGameState* BlasterGameState = Cast<ABlasterGameState>(UGameplayStatics::GetGameState(this));ABlasterPlayerState* BlasterPlayerState = GetPlayerState<ABlasterPlayerState>();if (BlasterGameState && BlasterPlayerState){TArray<ABlasterPlayerState*> TopPlayers = BlasterGameState->TopScoringPlayers;FString InfoTextString;if (TopPlayers.Num() == 0){InfoTextString = FString("There is no Winner");}else if (TopPlayers.Num() == 1 && TopPlayers[0] == BlasterPlayerState){InfoTextString = FString("You are Winner");}else if(TopPlayers.Num() == 1){InfoTextString = FString::Printf(TEXT("Winner: \n%s"),*TopPlayers[0]->GetPlayerName());}else if(TopPlayers.Num() > 1){InfoTextString = FString::Printf(TEXT("Winner: \n%s"), *TopPlayers[0]->GetPlayerName());for (auto TiedPlayer : TopPlayers){InfoTextString.Append(FString::Printf(TEXT("%s\n"),*TiedPlayer->GetPlayerName()));}}BlasterHUD->Announcement->InfoText->SetText(FText::FromString(InfoTextString));}}}ABlasterCharacter* BasterCharacter = Cast<ABlasterCharacter>(GetPawn());if (BasterCharacter && BasterCharacter->GetCombat()){BasterCharacter->bDisableGameplay = true;BasterCharacter->GetCombat()->FireButtonPressed(false);}
}
5.重新启动游戏如果当前状态时Cooldown判断当前比赛时间是否结束,重新启动游戏
namespace MatchState
{extern BLASTER_API const FName Cooldown;// 到达了比赛持续时间,展示获胜者并开始冷却时间}
else if (MatchState == MatchState::Cooldown){CountdownTime = CooldownTime + WarmupTime + MatchTime - GetWorld()->GetTimeSeconds() + LevelStartintTime;if (CountdownTime < 0.f){RestartGame();}}namespace MatchState
{const FName Cooldown = FName(TEXT("Cooldown"));}