question

Greggory Addison avatar image
Greggory Addison asked

Creating A Matchmaking Ticket In C++ UE5

Im following a blueprint tutorial and trying to convert it to C++ but i'm having some difficulties. When using the C++ Static function UPlayFabMultiplayerAPI::CreateMatchMakingTicket it takes in 4 parameters a FMultiplayerCreateMatchmakingTicketRequest, a success delegate, a failure delegat and a custom data object. Im able to setup the ticket struct pretty easily. I'm struggling with the delegates. They dont exist in the playfab namespace so I cannot just use "CreateUObject" Like i've done for all the other delegates I've used for logging in and registering the user. Does anyone know the correct syntax to fill out this function in C++ with no errors?

/** Create a matchmaking ticket as a client. */
UFUNCTION(BlueprintCallable, Category = "PlayFab | Multiplayer | Matchmaking ", meta = (BlueprintInternalUseOnly = "true"))
    static UPlayFabMultiplayerAPI* CreateMatchmakingTicket(FMultiplayerCreateMatchmakingTicketRequest request,
        FDelegateOnSuccessCreateMatchmakingTicket onSuccess,
        FDelegateOnFailurePlayFabError onFailure, UObject* customData);
sdksMatchmakingAuthenticationmultiplayerunreal
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

1 Answer

·
Gosen Gao avatar image
Gosen Gao answered

The source code you are referring to is under the UnrealMarketplacePlugin/5.0/PlayFabPlugin/PlayFab/Source/PlayFab/ folder and it is for blueprint. We have the UnrealMarketplacePlugin/5.0/PlayFabPlugin/PlayFab/Source/PlayFabCpp/ folder for CPP projects. Since you are implementing a CPP project, as we mention here, “Open the YourProject.Build.cs file and update the PublicDependencyModuleNames with "PlayFab" (for the Blueprints module) and "PlayFabCpp" (for the C++ module)”, please follow the documentation to use the headers under PlayFabCpp. And here is a sample for your reference.

//Sample.cpp

#include "LoginActor.h"
#include "Core/PlayFabClientAPI.h"
#include "Core/PlayFabMultiplayerAPI.h"

ALoginActor::ALoginActor()
{
    PrimaryActorTick.bCanEverTick = true;
}

void ALoginActor::BeginPlay()
{
    Super::BeginPlay();

    GetMutableDefault<UPlayFabRuntimeSettings>()->TitleId = TEXT("XXXXX");

    clientAPI = IPlayFabModuleInterface::Get().GetClientAPI();
    multiplayerAPI = IPlayFabModuleInterface::Get().GetMultiplayerAPI();

    PlayFab::ClientModels::FLoginWithCustomIDRequest request;
    request.CustomId = TEXT("Gosen");
    request.CreateAccount = true;

    clientAPI->LoginWithCustomID(request,
        PlayFab::UPlayFabClientAPI::FLoginWithCustomIDDelegate::CreateUObject(this, &ALoginActor::OnSuccess),
        PlayFab::FPlayFabErrorDelegate::CreateUObject(this, &ALoginActor::OnError)
    );
}

void ALoginActor::OnSuccess(const PlayFab::ClientModels::FLoginResult& Result)
{
    UE_LOG(LogTemp, Log, TEXT("Congratulations, you made your first successful API call!"));
    PlayFab::MultiplayerModels::FCreateMatchmakingTicketRequest request;
    request.GiveUpAfterSeconds = 120;
    request.QueueName = TEXT("QuickMatch");
    request.Creator = PlayFab::MultiplayerModels::FMatchmakingPlayer();
    request.Creator.Entity.Id = Result.EntityToken.Get()->Entity.Get()->Id;
    request.Creator.Entity.Type = Result.EntityToken.Get()->Entity.Get()->Type;

    multiplayerAPI->CreateMatchmakingTicket(request,
        PlayFab::UPlayFabMultiplayerAPI::FCreateMatchmakingTicketDelegate::CreateUObject(this, &ALoginActor::OnCMTS),
        PlayFab::FPlayFabErrorDelegate::CreateUObject(this, &ALoginActor::OnCMTF)
    );
}

void ALoginActor::OnError(const PlayFab::FPlayFabCppError& ErrorResult) const
{
    UE_LOG(LogTemp, Error, TEXT("Something went wrong with your first API call.\nHere's some debug information:\n%s"), *ErrorResult.GenerateErrorReport());
}

void ALoginActor::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);
}

void ALoginActor::OnCMTS(const PlayFab::MultiplayerModels::FCreateMatchmakingTicketResult& Result) const
{
    UE_LOG(LogTemp, Log, TEXT("Ticket created, and Ticket is : %s"), * Result.TicketId);
}

void ALoginActor::OnCMTF(const PlayFab::FPlayFabCppError& ErrorResult) const
{
    UE_LOG(LogTemp, Error, TEXT("Something went wrong.\nHere's some debug information:\n%s"), *ErrorResult.GenerateErrorReport());
}


//Sample.h

#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "PlayFab.h"
#include "Core/PlayFabError.h"
#include "Core/PlayFabClientDataModels.h"
#include "Core/PlayFabMultiplayerDataModels.h"
#include "LoginActor.generated.h"
UCLASS()
class ALoginActor : public AActor
{
    GENERATED_BODY()
public:
    ALoginActor();
    virtual void BeginPlay() override;
    void OnSuccess(const PlayFab::ClientModels::FLoginResult& Result);
    void OnError(const PlayFab::FPlayFabCppError& ErrorResult) const;

    void OnCMTS(const PlayFab::MultiplayerModels::FCreateMatchmakingTicketResult& Result) const;
    void OnCMTF(const PlayFab::FPlayFabCppError& ErrorResult) const;

    virtual void Tick(float DeltaSeconds) override;
private:
    PlayFabClientPtr clientAPI = nullptr;
    PlayFabMultiplayerPtr multiplayerAPI = nullptr;
};
5 comments
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Greggory Addison avatar image Greggory Addison commented ·

I don't know if this is the correct solution but this compiled successfully. Still need to test it

UPlayFabMultiplayerAPI::FDelegateOnSuccessCreateMatchmakingTicket SuccessDelegate;
SuccessDelegate.BindUFunction(this, FName("OnCreateMatchmakingTicketSuccess"));

UPlayFabMultiplayerAPI::FDelegateOnFailurePlayFabError FailureDelegate;
FailureDelegate.BindUFunction(this, "OnCreateMatchmakingTicketError");

UPlayFabMultiplayerAPI::CreateMatchmakingTicket(MatchmakingTicketRequest, SuccessDelegate, FailureDelegate, nullptr);
0 Likes 0 ·
Greggory Addison avatar image Greggory Addison commented ·

This is a good example to see the API. But rarely would I log a player in and start matchmaking directly. So is the best practice to cache all the data I will need to pass to the Matchmake request and pull from those caches in a custom function that will run when the player decides to queue up for a match? Is it safe to cache this kind of data where the client can access it? If not what is the best place to do this?

0 Likes 0 ·
Gosen Gao avatar image Gosen Gao Greggory Addison commented ·

It is safe, since this is the data that the client can obtain, there is no problem with caching it.

0 Likes 0 ·
Greggory Addison avatar image Greggory Addison commented ·

Also what is the difference between FMultiplayerCreateMatchmakingTicketRequest and FCreateMatchmakingTicketRequest?

0 Likes 0 ·
Gosen Gao avatar image Gosen Gao Greggory Addison commented ·

There is not much difference, one is defined in the blueprint module and the other is defined in the C++ module, please use it based on the corresponding module.

0 Likes 0 ·

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Error rendering WebPanel (widgets/consolidation-widget.ftl): org.hibernate.hql.internal.ast.QuerySyntaxException: AvailableConsolidation is not mapped [from AvailableConsolidation up where up.node = :node]