毎週のリーダーボードメニューを追加する - 毎週のリーダーボード - (Unreal Engine モジュール)
注釈:本資料はAI技術を用いて翻訳されています。
メニューの内容
このチュートリアルでは、毎週のリーダーボードを表示するために使用するウィジェットを準備する方法を学びます。ウィジェットはリソースセクションで入手でき、以下で構成されています:
-
LeaderboardsWidget: Byte Warsのゲームモード(シングルプレイヤー、エリミネーション、チームデスマッチ)に基づいてリーダーボードタイプを選択するボタンを表示するC++クラスです。このクラスを使用して、表示するリーダーボードを選択します。これは全期間リーダーボードで使用したのと同じクラスです。- Header file:
/Source/AccelByteWars/TutorialModules/Engagement/LeaderboardEssentials/UI/LeaderboardsWidget.h - CPP file:
/Source/AccelByteWars/TutorialModules/Engagement/LeaderboardEssentials/UI/LeaderboardsWidget.cpp - Blueprint widget:
/Content/TutorialModules/Engagement/LeaderboardEssentials/UI/W_Leaderboards.uasset
- Header file:
-
W_LeaderboardPeriod: リーダーボードの期間を選択するボタンを表示するBlueprintウィジェットです。これは全期間リーダーボードで使用したのと同じウィジェットです。- Blueprint widget:
/Content/TutorialModules/Engagement/LeaderboardEssentials/UI/W_LeaderboardPeriod.uasset
- Blueprint widget:
-
LeaderboardWeeklyWidget_Starter: リーダーボードの毎週のランキングを表示するために使用するC++クラスです。- Header file:
/Source/AccelByteWars/TutorialModules/Engagement/PeriodicLeaderboard/UI/LeaderboardWeeklyWidget_Starter.h - CPP file:
/Source/AccelByteWars/TutorialModules/Engagement/PeriodicLeaderboard/UI/LeaderboardWeeklyWidget_Starter.cpp - Blueprint widget:
/Content/TutorialModules/Engagement/PeriodicLeaderboard/UI/W_LeaderboardWeekly_Starter.uasset
- Header file:
-
LeaderboardWidgetEntry: プレイヤーのランクやスコアなど、個々のプレイヤーのリーダーボード情報を表示するために使用するC++クラスです。これは全期間リーダーボードで使用したのと同じクラスです。- Header file:
/Source/AccelByteWars/TutorialModules/Engagement/LeaderboardEssentials/UI/LeaderboardWidgetEntry.h - CPP file:
/Source/AccelByteWars/TutorialModules/Engagement/LeaderboardEssentials/UI/LeaderboardWidgetEntry.cpp - Blueprint widget:
/Content/TutorialModules/Engagement/LeaderboardEssentials/UI/W_LeaderboardEntry.uasset
- Header file:
これらのウィジェットがどのように構築されているかの詳細を見てみましょう。
リーダーボードウィジェット
以下は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;
}
リーダーボード期間ウィジェット
以下はW_LeaderboardPeriod Blueprintウィジェットのプレビューです。このウィジェットは、リーダーボードの期間を選択するボタンを表示します。期間ボタンは、ゲームをプレイするときに動的に生成されます。このウィジェットには、全期間と毎週の2種類のリーダーボード期間があります。このチュートリアルでは、毎週のリーダーボード期間を実装します。

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

上記のコンポーネントはLeaderboardWeeklyWidget_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::Loading);
リーダーボードはすべてのプレイヤーをランク付けするため、表示するリーダーボードのランクを制限したい場合があります。表示されるデフォルトの制限は10ですが、LeaderboardWeeklyWidget_Starterクラスのヘッダーファイルで変更できます。
protected:
// ...
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
int32 ResultLimit = 10;
リーダーボードエントリーウィジェット
これは、毎週のリーダーボードウィジェットのリストと現在ログインしているプレイヤーのランクのエントリーウィジェットとして使用されます。このウィジェットは、表示名、ランク、スコアなど、個々のプレイヤーのリーダーボード情報を表示します。以下は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の準備
このセクションでは、ウィジェットを準備する方法を学びます。
-
LeaderboardWeeklyWidget_Starterクラスのヘッダーファイルを開きます。次に、以下の関数を宣言します:protected:
// ...
void GetWeeklyRankings();
// ...
void GetPlayerWeeklyRanking();
// ...
void DisplayPlayerWeeklyRank(const ULeaderboardRank* PlayerRank); -
LeaderboardWeeklyWidget_StarterクラスのCPPファイルを開きます。GetWeeklyRankings()関数の定義を作成します。この関数を使用して、特定の範囲(例:ランク0から10)の毎週のリーダーボードランキングを取得して表示します。今のところ、空のままにしておきます。void ULeaderboardWeeklyWidget_Starter::GetWeeklyRankings()
{
// ...
} -
同じファイルで、
GetPlayerWeeklyRanking()関数の定義を作成します。この関数を使用して、GetWeeklyRankings()関数で取得したリストにプレイヤーが含まれていない場合(例:プレイヤーがトップ10に含まれていない場合)に、ログインしているプレイヤーの毎週のランクを取得します。今のところ、空のままにしておきます。void ULeaderboardWeeklyWidget_Starter::GetPlayerWeeklyRanking()
{
// ...
} -
DisplayPlayerWeeklyRank()関数の定義を作成します。この関数を使用して、リストの下のエントリーに、ログインしているプレイヤーの毎週のランクを具体的に表示します。void ULeaderboardWeeklyWidget_Starter::DisplayPlayerWeeklyRank(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()関数に、以下のコードを追加します。このコードは、リーダーボードエントリーリストパネルをクリアし、空の状態を表示します。void ULeaderboardWeeklyWidget_Starter::NativeOnActivated()
{
// ...
// Reset widgets.
PlayerRankPanel->SetVisibility(ESlateVisibility::Collapsed);
Lv_Leaderboard->ClearListItems();
Ws_Leaderboard->SetWidgetState(EAccelByteWarsWidgetSwitcherState::Loading);
// ...
} -
プロジェクトをビルドし、Unreal Engine Editorで開きます。Editorで、
/Content/TutorialModules/Engagement/PeriodicLeaderboard/に移動します。DA_PeriodicLeaderboardというデータアセットがあります。それを開き、Is Starter Mode Activeを有効にします。次に、データアセットを再度保存します。これにより、ウィジェットがアクティブになり、ゲームをプレイするときにそれらをナビゲートできるようになります。
-
Editorでゲームをプレイし、ログインすると、実装が成功した場合、Leaderboard > Single Player > Weeklyにナビゲートできるようになります。
リソース
- このチュートリアルセクションで使用されるファイルは、Unreal Byte Wars GitHubリポジトリで入手できます。
- AccelByteWars/Content/TutorialModules/Engagement/PeriodicLeaderboard/DA_PeriodicLeaderboard.uasset
- 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/PeriodicLeaderboard/UI/W_LeaderboardWeekly_Starter.uasset
- AccelByteWars/Source/AccelByteWars/TutorialModules/Engagement/PeriodicLeaderboard/UI/LeaderboardWeeklyWidget_Starter.h
- AccelByteWars/Source/AccelByteWars/TutorialModules/Engagement/PeriodicLeaderboard/UI/LeaderboardWeeklyWidget_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