リーダーボードメニューを追加する - 全期間のリーダーボード - (Unreal Engine モジュール)
注釈:本資料はAI技術を用いて翻訳されています。
メニューの内容
このチュートリアルでは、リーダーボードを表示するために使用するウィジェットの準備方法を学びます。ウィジェットはリソースセクションで入手でき、以下のファイルで構成されています。
LeaderboardsWidget: Byte Wars のゲームモード(シングルプレイヤー、エリミネーション、チームデスマッチ)に基づいてリーダーボードタイプを選択するボタンを表示する C++ クラスです。このクラスを使用して、表示するリーダーボードを選択します。- ヘッダーファイル:
/Source/AccelByteWars/TutorialModules/Engagement/LeaderboardEssentials/UI/LeaderboardsWidget.h - CPP ファイル:
/Source/AccelByteWars/TutorialModules/Engagement/LeaderboardEssentials/UI/LeaderboardsWidget.cpp - Blueprint ウィジェット:
/Content/TutorialModules/Engagement/LeaderboardEssentials/UI/W_Leaderboards.uasset
- ヘッダーファイル:
W_LeaderboardPeriod: リーダーボードの期間を選択するボタンを表示するウィジェット Blueprint です。- Blueprint ウィジェット:
/Content/TutorialModules/Engagement/LeaderboardEssentials/UI/W_LeaderboardPeriod.uasset
- Blueprint ウィジェット:
LeaderboardAllTimeWidget_Starter: リーダーボードのランキングを表示するために使用する C++ クラスです。- ヘッダーファイル:
/Source/AccelByteWars/TutorialModules/Engagement/LeaderboardEssentials/UI/LeaderboardAllTimeWidget_Starter.h - CPP ファイル:
/Source/AccelByteWars/TutorialModules/Engagement/LeaderboardEssentials/UI/LeaderboardAllTimeWidget_Starter.cpp - Blueprint ウィジェット:
/Content/TutorialModules/Engagement/LeaderboardEssentials/UI/W_LeaderboardAllTime_Starter.uasset
- ヘッダーファイル:
LeaderboardWidgetEntry: プレイヤーのランクやスコアなど、個々のプレイヤーのリーダーボード情報を表示するために使用する C++ クラスです。- ヘッダーファイル:
/Source/AccelByteWars/TutorialModules/Engagement/LeaderboardEssentials/UI/LeaderboardWidgetEntry.h - CPP ファイル:
/Source/AccelByteWars/TutorialModules/Engagement/LeaderboardEssentials/UI/LeaderboardWidgetEntry.cpp - Blueprint ウィジェット:
/Content/TutorialModules/Engagement/LeaderboardEssentials/UI/W_LeaderboardEntry.uasset
- ヘッダーファイル:
これらのウィジェットがどのように構成されているかの詳細を見ていきましょう。
Leaderboards ウィジェット
以下は W_Leaderboards Blueprint ウィジェットのプレビューです。このウィジェットは、Byte Wars のゲームモード(シングルプレイヤー、エリミネーション、チームデスマッチ)に基づいてリーダーボードタイプを選択するボタンを表示します。

上記のボタンは LeaderboardsWidget クラスのヘッダーファイルで宣言されています。
protected:
// ...
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional, BlueprintProtected = true, AllowPrivateAccess = true))
UCommonButtonBase* Btn_SinglePlayer;
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional, BlueprintProtected = true, AllowPrivateAccess = true))
UCommonButtonBase* Btn_Elimination;
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional, BlueprintProtected = true, AllowPrivateAccess = true))
UCommonButtonBase* Btn_TeamDeathmatch;
ボタンがクリックされると、以下の関数が呼び出されます。基本的に、この関数はゲームモードに基づいてリーダーボードタイプを設定し、リーダーボードの期間を選択するために W_LeaderboardPeriod ウィジェットを表示します。
void ULeaderboardsWidget::OpenLeaderboardsPeriod(const FString InGameMode)
{
LeaderboardGameMode = InGameMode;
UAccelByteWarsGameInstance* GameInstance = StaticCast<UAccelByteWarsGameInstance*>(GetWorld()->GetGameInstance());
ensure(GameInstance);
UAccelByteWarsBaseUI* BaseUIWidget = GameInstance->GetBaseUIWidget();
ensure(BaseUIWidget);
BaseUIWidget->PushWidgetToStack(EBaseUIStackType::Menu, LeaderboardsPeriodWidgetClass);
}
選択されたゲームモードを取得するには、以下のヘルパー関数を使用します。
public:
static FString GetLeaderboardGameMode()
{
return LeaderboardGameMode;
}
Leaderboard Period ウィジェット
以下は W_LeaderboardPeriod Blueprint ウィジェットのプレビューです。このウィジェットは、リーダーボードの期間を選択するボタンを表示します。期間ボタンはゲームをプレイするときに動的に生成されるため、エディタ上ではボタンは表示されません。リーダーボードの期間には、全期間とサイクルの 2 種類があります。このチュートリアルでは、全期間のリーダーボード期間を実装します。

全期間リーダーボードウィジェット
全期間リーダーボードウィジェットには、クエリステータスの各状態を表すいくつかの状態があります:読み込み中、空、空でない(ランキングのリストを表示)。これらの状態は、カスタム Widget Switcher である UAccelByteWarsWidgetSwitcher を使用して実現されています。リスト自体は、エントリウィジェットクラスを受け取り、エントリを動的に生成する List View を使用して実装されています。このウィジェットには、リストビューの下に、現在ログインしているプレイヤーのランクを表示するエントリも 1 つ含まれています。以下は、読み込み中の状態の W_LeaderboardAllTime_Starter Blueprint ウィジェットのプレビューです。

上記のコンポーネントは LeaderboardAllTimeWidget_Starter クラスのヘッダーファイルで宣言されています。
protected:
// ...
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional, BlueprintProtected = true, AllowPrivateAccess = true))
UAccelByteWarsWidgetSwitcher* Ws_Leaderboard;
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional, BlueprintProtected = true, AllowPrivateAccess = true))
UListView* Lv_Leaderboard;
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional, BlueprintProtected = true, AllowPrivateAccess = true))
ULeaderboardWidgetEntry* PlayerRankPanel;
このウィジェットの状態を変更するには、Ws_Leaderboard->SetWidgetState() を呼び出します。以下は、状態を空の状態に変更する方法の例です。
// ...
Ws_Leaderboard->SetWidgetState(EAccelByteWarsWidgetSwitcherState::Empty);
リーダーボードはすべてのプレイヤーをランク付けするため、表示するリーダーボードのランクを制限したい場合があります。表示されるデフォルトの制限は 10 ですが、LeaderboardAllTimeWidget_Starter クラスのヘッダーファイルで変更できます。
protected:
// ...
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
int32 ResultLimit = 10;
Leaderboard Entry ウィジェット
これは、全期間リーダーボードウィジェットのリストと現在ログインしているプレイヤーのランクのエントリウィジェットとして使用されます。このウィジェットは、表示名、ランク、スコアなど、個々のプレイヤーのリーダーボード情報を表示します。以下は W_LeaderboardEntry Blueprint ウィジェットのプレビューです。

上記のコンポーネントは LeaderboardWidgetEntry クラスのヘッダーファイルで宣言されています。
protected:
// ...
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional, BlueprintProtected = true, AllowPrivateAccess = true))
UTextBlock* Tb_Rank;
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional, BlueprintProtected = true, AllowPrivateAccess = true))
UTextBlock* Tb_DisplayName;
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional, BlueprintProtected = true, AllowPrivateAccess = true))
UTextBlock* Tb_Score;
List View では、エントリウィジェットが IUserObjectListEntry インターフェースを実装する必要があります。このウィジェットの親である UAccelByteWarsWidgetEntry を見ると、IUserObjectListEntry が実装されていることがわかります。ウィジェットがエントリウィジェットとして正しく機能するためには、NativeOnListItemObjectSet を実装する必要があります。この関数はセットアップ関数です。ここで、すべてのユーザーインターフェース(UI)のセットアップを行う必要があります。これはすでに実装されているので、任意の List View に使用するか、NativeOnListItemObjectSet() 関数を呼び出して手動でセットアップすることができます。
void ULeaderboardWidgetEntry::NativeOnListItemObjectSet(UObject* ListItemObject)
{
Super::NativeOnListItemObjectSet(ListItemObject);
const ULeaderboardRank* LeaderboardRank = Cast<ULeaderboardRank>(ListItemObject);
if (!LeaderboardRank)
{
return;
}
const bool bUnranked = LeaderboardRank->Rank <= 0;
// Display the player's rank. If the player is not ranked, display it as #?.
Tb_Rank->SetText(bUnranked ? FText::FromString(TEXT("?")) : FText::AsNumber(LeaderboardRank->Rank));
// Display the player's display name.
Tb_DisplayName->SetText(FText::FromString(LeaderboardRank->DisplayName));
// Display the player's score. If the player is not ranked, display it as empty.
Tb_Score->SetText(bUnranked ? FText::FromString(TEXT("")) : FText::AsNumber(LeaderboardRank->Score));
}
UI の準備
このセクションでは、ウィジェットを準備する方法を学びます。
-
LeaderboardAllTimeWidget_Starterクラスのヘッダーファイルを開きます。次に、以下の関数を宣言します。protected:
// ...
void GetRankings();
// ...
void GetPlayerRanking();
// ...
void DisplayPlayerRank(const ULeaderboardRank* PlayerRank); -
LeaderboardAllTimeWidget_Starterクラスの CPP ファイルを開きます。GetRankings()関数の定義を作成します。この関数を使用して、特定の範囲(例:ランク 0 から 10)のリーダーボードランキングを取得して表示します。今のところ、空のままにしておきます。void ULeaderboardAllTimeWidget_Starter::GetRankings()
{
// ...
} -
同じファイルで、
GetPlayerRanking()関数の定義を作成します。この関数を使用して、GetRankings()関数で取得したリストにプレイヤーが含まれていない場合(例:プレイヤーがトップ 10 に含まれていない場合)に、ログインしているプレイヤーのランクを取得します。今のところ、空のままにしておきます。void ULeaderboardAllTimeWidget_Starter::GetPlayerRanking()
{
// ...
} -
DisplayPlayerRank()関数の定義を作成します。この関数を使用して、リストの下にある 1 つのエントリに、ログインしているプレイヤーのランクを具体的に表示します。void ULeaderboardAllTimeWidget_Starter::DisplayPlayerRank(const ULeaderboardRank* PlayerRank)
{
// Display player rank information.
const bool bIsRanked = (PlayerRank && PlayerRank->Rank > 0);
ULeaderboardRank* PlayerRankToDisplay = NewObject<ULeaderboardRank>();
PlayerRankToDisplay->Init(
bIsRanked ? PlayerRank->UserId : nullptr,
bIsRanked ? PlayerRank->Rank : -1,
bIsRanked ? RANKED_MESSAGE.ToString() : UNRANKED_MESSAGE.ToString(),
bIsRanked ? PlayerRank->Score : -1);
PlayerRankPanel->SetLeaderboardRank(PlayerRankToDisplay);
PlayerRankPanel->SetVisibility(ESlateVisibility::HitTestInvisible);
} -
NativeOnActivated()関数に、以下のコードを追加します。この関数は、W_LeaderboardAllTime_Starterが表示されたときにGetPlayerRanking()関数を呼び出します。void ULeaderboardAllTimeWidget_Starter::NativeOnActivated()
{
// ...
Super::NativeOnActivated();
// Reset widgets.
PlayerRankPanel->SetVisibility(ESlateVisibility::Collapsed);
Ws_Leaderboard->SetWidgetState(EAccelByteWarsWidgetSwitcherState::Empty);
Lv_Leaderboard->ClearListItems();
// Get leaderboard rankings.
GetRankings();
} -
プロジェクトをビルドし、Unreal Engine エディタで開きます。エディタで、
/Content/TutorialModules/Engagement/LeaderboardEssentials/に移動します。DA_LeaderboardEssentialsというデータアセットがあります。これを開き、Is Starter Mode Activeを有効にします。次に、データアセットを保存します。これにより、ウィジェットがアクティブになり、ゲームをプレイするときにウィジェット間を移動できるようになります。
-
エディタでゲームをプレイし、ログインします。実装が成功していれば、Leaderboard > Single Player > All time に移動できるようになります。
リソース
-
このチュートリアルセクションで使用されているファイルは、Unreal Byte Wars GitHub リポジトリで入手できます。
- AccelByteWars/Content/TutorialModules/Engagement/LeaderboardEssentials/UI/W_Leaderboards.uasset
- AccelByteWars/Source/AccelByteWars/TutorialModules/Engagement/LeaderboardEssentials/UI/LeaderboardsWidget.h
- AccelByteWars/Source/AccelByteWars/TutorialModules/Engagement/LeaderboardEssentials/UI/LeaderboardsWidget.cpp
- AccelByteWars/Content/TutorialModules/Engagement/LeaderboardEssentials/UI/W_LeaderboardPeriod.uasset
- AccelByteWars/Content/TutorialModules/Engagement/LeaderboardEssentials/UI/W_LeaderboardAllTime_Starter.uasset
- AccelByteWars/Source/AccelByteWars/TutorialModules/Engagement/LeaderboardEssentials/UI/LeaderboardAllTimeWidget_Starter.h
- AccelByteWars/Source/AccelByteWars/TutorialModules/Engagement/LeaderboardEssentials/UI/LeaderboardAllTimeWidget_Starter.cpp
- AccelByteWars/Content/TutorialModules/Engagement/LeaderboardEssentials/UI/W_LeaderboardEntry.uasset
- AccelByteWars/Source/AccelByteWars/TutorialModules/Engagement/LeaderboardEssentials/UI/LeaderboardWidgetEntry.h
- AccelByteWars/Source/AccelByteWars/TutorialModules/Engagement/LeaderboardEssentials/UI/LeaderboardWidgetEntry.cpp