はじめに

「UE5でEpic Online Services(EOS)を使ってみる」の続きです。
ログインの実装が必要なので、未実装の方は準備編ログイン編をご確認ください。

リーダーボード(ランキング)は、統計データに対して期間を指定することで、その間のリーダーボードを作成できます。
今回は前回作成した統計データのリーダーボードを作成します。

目次

この章では、リーダーボード機能に必要な実装を行っていきます。
ポータルサイトにて、リーダーボードに必要な設定を行い、
必要なクラスを作成してC++を実装し、Blueprintで実行出来る状態にしてテストを行います。

  1. Developer Portal
  2. クラス作成
  3. C++
  4. Blueprint
  5. テスト

 

1.Developer Portal

Developer Portalでリーダーボードを作成します。

ゲームサービス>リーダーボードに遷移して、「リーダーボード作成」をボタンを押します。
作成窓が開くので、各項目に以下を入力して作成。
・リーダーボード名:SCORE_RANK
・統計データ:SCORE_SUM
・開始日:今日の日付
・このリーダーボードの期限が切れないようにしてください:チェック



 

2.クラス作成

リーダーボードの取得用のクラスを作成します。

2-1.C++クラス
OnlineBlueprintCallProxyBaseを親クラスに指定して、EOS_GetLeaderboardをC++クラスで作成します。


 

3.C++

C++を以下で実装します。

EOS_DataDefinition.h(以下を追加)

USTRUCT(BlueprintType)
struct FRankingData
{
  GENERATED_BODY()

  UPROPERTY(EditAnywhere, BlueprintReadWrite)
  int32 Rank;

  UPROPERTY(EditAnywhere, BlueprintReadWrite)
  FString NickName;

  UPROPERTY(EditAnywhere, BlueprintReadWrite)
  int32 Score;
};

EOS_GetLeaderboard.h

#pragma once

#include "CoreMinimal.h"
#include "Net/OnlineBlueprintCallProxyBase.h"
#include "Interfaces/OnlineLeaderboardInterface.h"
#include "EOS_DataDefinition.h"
#include "EOS_GetLeaderboard.generated.h"

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnGetLeaderboardRetrieved, const TArray<FRankingData>&, RankingData);

UCLASS()
class EOS_API UEOS_GetLeaderboard : public UOnlineBlueprintCallProxyBase
{
  GENERATED_BODY()

  UPROPERTY(BlueprintAssignable)
  FOnGetLeaderboardRetrieved OnSuccess;

  UPROPERTY(BlueprintAssignable)
  FOnGetLeaderboardRetrieved OnFailure;

  UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true", WorldContext = "WorldContextObject"), Category = "EOS")
  static UEOS_GetLeaderboard* GetLeaderboard(UObject* WorldContextObject, FName LeaderboardName, int32 Range, int32 AroundRank);

  virtual void Activate() override;

private:
  void OnGetLeaderboardComplete(const bool bWasSuccessful, FOnlineLeaderboardReadRef LeaderboardRef);

private:
  UWorld* World;
  TWeakObjectPtr<UObject> WorldContextObject;
  FName Leaderboard Name;
  int32 Range;
  int32 Around Rank;
  TArray<FRankingData> RankingData;
};

EOS_GetLeaderboard.cpp

#include "OnlineSubsystemUtils.h"
#include "EOS_GetLeaderboard.h"

UEOS_GetLeaderboard* UEOS_GetLeaderboard::GetLeaderboard(UObject* WorldContextObject, FName LeaderboardName, int32 Range, int32 AroundRank)
{
  UEOS_GetLeaderboard* Leaderboard = NewObject<UEOS_GetLeaderboard>();
  Leaderboard->WorldContextObject = WorldContextObject;
  Leaderboard->LeaderboardName = LeaderboardName;
  Leaderboard->Range = Range;
  Leaderboard->AroundRank = AroundRank;

  return Leaderboard;
}

void UEOS_GetLeaderboard::Activate()
{
  RankingData.Empty();

  World = GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull);

  if (!World)
  {
    UE_LOG(LogTemp, Error, TEXT("Leaderboard:Worldの取得に失敗"));
    OnFailure.Broadcast(RankingData);
    return;
  }

  IOnlineSubsystem* SubsystemRef = Online::GetSubsystem(World);
  IOnlineIdentityPtr IdentityPointerRef = SubsystemRef->GetIdentityInterface();
  IOnlineLeaderboardsPtr  LeaderboardsPointerRef = SubsystemRef->GetLeaderboardsInterface();

  if (LeaderboardsPointerRef)
  {
    FOnlineLeaderboardReadRef LeaderboardReadRef = MakeShared<FOnlineLeaderboardRead, ESPMode::ThreadSafe>();
    LeaderboardReadRef->LeaderboardName = LeaderboardName;
    LeaderboardsPointerRef->OnLeaderboardReadCompleteDelegates.AddUObject(this, &UEOS_GetLeaderboard::OnGetLeaderboardComplete, LeaderboardReadRef);
    LeaderboardsPointerRef->ReadLeaderboardsAroundRank(AroundRank, Range, LeaderboardReadRef);
    return;
  }

  OnFailure.Broadcast(RankingData);
}

void UEOS_GetLeaderboard::OnGetLeaderboardComplete(const bool bWasSuccessful, FOnlineLeaderboardReadRef LeaderboardReadRef)
{
  if (bWasSuccessful)
  {
    UE_LOG(LogTemp, Warning, TEXT("ランキング取得成功"));
    RankingData.Empty();

    for (auto Row : LeaderboardReadRef->Rows)
    {
      FRankingData RankData;
      RankData.Rank = Row.Rank;
      RankData.NickName = Row.NickName;
      Row.Columns[FName("None")].GetValue(RankData.Score);

      RankingData.Add(RankData);
    }
    FString log = LeaderboardReadRef->ToLogString();
    UE_LOG(LogTemp, Warning, TEXT("%s"), *log);

    OnSuccess.Broadcast(RankingData);
  }
  else
  {
    FString log = LeaderboardReadRef->ToLogString();
    UE_LOG(LogTemp, Warning, TEXT("ランキング取得失敗 - %s"), *log);
    OnFailure.Broadcast(RankingData);
  }
}

 

5.Blueprint

Blueprintを以下で実装します。

OnLeaderboardButton:EOSからランキングデータを配列で取得します。各項目に以下を入力します。
・LeaderBoardName:リーダーボード名
・Range:取得する順位の範囲
・AroundRank:基準となる順位


 

6.テスト

6-1.リーダーボード取得
ログイン後にOnLeaderboardButtonを実行します。
ここで取得しているNameはEpicアカウントのニックネームになります。

6-2.Developer Portal
ゲームサービス>リーダーボード>詳細の表示から、Developer Portal上でランキングを確認できます。
ここで表示される名前は製品ユーザーIDになります。


おわり

お疲れ様です。
以上でリーダーボード備は終わりです、次はプレイヤーデータ編です。