前回の続き。
なんかもう専門的すぎる話で一体誰に需要があるのか分からんですが、まあ世界のどこかの誰かにぶっ刺さればいいなくらいの気持ちでいきます。逆に専門的じゃないことはChatGPTに聞けばええんや。
お約束 | |
---|---|
この記事作成にあたって使用した主なUnreal Engine バージョン | UE 5.3.2 |
本日のゴール
EOSでマッチメイキングする
そもそもマッチメイキングとは…?
マッチメイキングとはそもそもなんなのでしょう?ChatGPTに聞いたところ「プレイヤー同士を適切な条件で自動的にマッチングし、対戦や協力プレイを行えるようにする仕組みのこと」のようです。
種類がいくつかあるらしく、スキルレベルやランクを基準にしてマッチングさせる方式、カジュアルマッチでとにかくマッチングさせる方式、地域でマッチングさせる方式、役割を基準にしてマッチングさせる方式(役職が被らないように)
などです。このページではランクを基準にしてマッチングさせる方式について解説しますが、基本はどれも実現できると思います。
Lyraでのセッション検索の結果
そもそも、Lyraではセッションを作成する(いわゆる"ホスト"する)こともできれば、この作成されたセッションを検索することもできますし、その検索されたセッションに接続してゲームに参加すること(いわゆる"ジョイン")もできます。
Lyraでセッションを検索する手順は下記になります。
このResultsからは、For Each Loopでそれぞれの結果を取り出すことができます。それぞれの結果に対して、Get String Settingノードで特定の情報を引き出すことが可能です。例えばセッションを作成したプレイヤーのレベルを格納すればランクマッチに使えそうですね。※情報はStringで出てくるので、後でintに変換してください。
- void UCommonSessionSubsystem::CreateOnlineSessionInternalOSSv1(ULocalPlayer* LocalPlayer, UCommonSession_HostSessionRequest* Request, int32 PlayerLevel)
- {
- const FName SessionName(NAME_GameSession);
- const int32 MaxPlayers = Request->GetMaxPlayers();
- const bool bIsPresence = Request->bUseLobbies; // Using lobbies implies presence
- IOnlineSubsystem* const OnlineSub = Online::GetSubsystem(GetWorld());
- check(OnlineSub);
- IOnlineSessionPtr Sessions = OnlineSub->GetSessionInterface();
- check(Sessions);
- FUniqueNetIdPtr UserId;
- if (LocalPlayer)
- {
- UserId = LocalPlayer->GetPreferredUniqueNetId().GetUniqueNetId();
- }
- else if (bIsDedicatedServer)
- {
- UserId = OnlineSub->GetIdentityInterface()->GetUniquePlayerId(0);
- }
- //@TODO: You can get here on some platforms while trying to do a LAN session, does that require a valid user id?
- if (ensure(UserId.IsValid()))
- {
- HostSettings = MakeShareable(new FCommonSession_OnlineSessionSettings(Request->OnlineMode == ECommonSessionOnlineMode::LAN, bIsPresence, MaxPlayers));
- HostSettings->bUseLobbiesIfAvailable = Request->bUseLobbies;
- HostSettings->bShouldAdvertise = true;
- HostSettings->Set(SETTING_GAMEMODE, Request->ModeNameForAdvertisement, EOnlineDataAdvertisementType::ViaOnlineService);
- HostSettings->Set(SETTING_MAPNAME, Request->GetMapName(), EOnlineDataAdvertisementType::ViaOnlineService);
- HostSettings->Set(SETTING_MATCHING_TIMEOUT, 120.0f, EOnlineDataAdvertisementType::ViaOnlineService);
- HostSettings->Set(SETTING_SESSION_TEMPLATE_NAME, FString(TEXT("GameSession")), EOnlineDataAdvertisementType::ViaOnlineService);//変更。DontAdvertiseから。
- HostSettings->Set(SETTING_ONLINESUBSYSTEM_VERSION, true, EOnlineDataAdvertisementType::ViaOnlineService);
- HostSettings->Set(SETTING_CUSTOM, FString::FromInt(PlayerLevel), EOnlineDataAdvertisementType::ViaOnlineService);//追加
- FSessionSettings& UserSettings = HostSettings->MemberSettings.Add(UserId.ToSharedRef(), FSessionSettings());
- UserSettings.Add(SETTING_GAMEMODE, FOnlineSessionSetting(FString("GameSession"), EOnlineDataAdvertisementType::ViaOnlineService));
- Sessions->CreateSession(*UserId, SessionName, *HostSettings);
- CheckVacantSlot();
- }
- else
- {
- OnCreateSessionComplete(SessionName, false);
- }
- }
- void UCommonSessionSubsystem::CreateOnlineSessionInternal(ULocalPlayer* LocalPlayer, UCommonSession_HostSessionRequest* Request, int32 PlayerLevel)
- {
- CreateSessionResult = FOnlineResultInformation();
- PendingTravelURL = Request->ConstructTravelURL();
- #if COMMONUSER_OSSV1
- CreateOnlineSessionInternalOSSv1(LocalPlayer, Request, PlayerLevel);
- #else
- CreateOnlineSessionInternalOSSv2(LocalPlayer, Request);
- #endif
- }
その②
- void UCommonSessionSubsystem::HostSession(APlayerController* HostingPlayer, UCommonSession_HostSessionRequest* Request, int32 PlayerLevel)
- {
- if (Request == nullptr)
- {
- ---(中略)---
- else
- {
- CreateOnlineSessionInternal(LocalPlayer, Request, PlayerLevel);
- }
- }
①
- UFUNCTION(BlueprintCallable, Category=Session)
- virtual void HostSession(APlayerController* HostingPlayer, UCommonSession_HostSessionRequest* Request, int32 PlayerLevel);
②
- void CreateOnlineSessionInternal(ULocalPlayer* LocalPlayer, UCommonSession_HostSessionRequest* Request, int32 PlayerLevel);
③
- void CreateOnlineSessionInternalOSSv1(ULocalPlayer* LocalPlayer, UCommonSession_HostSessionRequest* Request, int32 PlayerLevel);
これであとはブループリントでHostSessionをしたときに、プレイヤーのレベルを入れてあげればOKです。
ここで格納したPlayerLevelの情報が、それぞれJoinしたプレイヤーに伝わるわけです。なのでレベル差が多すぎるときにはそのセッションには参加しない、みたいなことができるようになります。
また、CUSTOMSEARCHINT1という、INT格納できる専用の変数が用意されているんですが、これはうまく使えなくて半年浪費しました。使い方をご存知の方がいれば教えて下さい…。私は使うの諦めてCUSTOMの方を使っています。
0 件のコメント:
コメントを投稿