This tutorial uses Unreal Engine 5.3 with Pragma Engine 0.1.0 to demonstrate integrating Pragma Engine party functionality with a third-party game engine. This guide assumes you are proficient with Unreal Editor.
In this tutorial, we’ll expand the MyPlayerController.h header file and MyPlayerController.cpp source file to implement functionality related to the Pragma Engine Friend service.
By the end of the tutorial, our game client will be able to send and receive friend invites, fetch friend data, and make basic and rich presence selections.
The code presented in this tutorial is simplified to give you an introduction to the game flow. An actual game would have a more sophisticated design, and the player experience may differ significantly.
We’ve built this barebones social screen to help you visualize the functionality presented in this tutorial:
The functions in this tutorial are built as UFunctions with the Exec and BlueprintCallable specifiers, meaning they can be executed by the in-game console and in a Blueprint or Level Blueprint graph. The Exec specifier is useful for quickly testing your functions.
The example tests in each section are meant to ensure your C++ code is working properly and are unlikely to represent a completed game design. Adapt the organization and naming to suit your project’s needs.
For convenience, we’ve included sample C++ files that contain all the code from this tutorial as well as the login/logout functionality, party functionality, and matchmaking functionality.
Note that you may need to update your #include statements as you progress through the tutorial.
Implement a InitializeFriend() function that initializes the Friend service. You can also choose to implement the following functionality into a general Initialize() function that also initializes the Party, Game Instance, and Presence services (see the relevant tutorials for examples).
Define InitializeFriend() in your MyPlayerController.cpp file:
voidAMyPlayerController::InitializeFriend(){UPragmaFriendApi::FOnCompleteDelegateFriendInitializeDelegate;FriendInitializeDelegate.BindWeakLambda(this,[this](constTPragmaResult<>&Result){if(Result.IsSuccessful()){UE_LOG(LogTemp,Display,TEXT("Friend service initialized."));}else{UE_LOG(LogTemp,Warning,TEXT("Friend service failed to initialize: %s"),*Result.Error().ToString());}});Player->FriendApi().Initialize(FriendInitializeDelegate);}
To test this functionality using the Unreal in-game console, issue InitializeFriend as each player client (e.g. test01 and test02).
To apply this functionality using Unreal Blueprints, you can call the InitializeFriend() function as part of another operation, such as upon login.
When the service is successfully initialized, you should see “FRiend service initialized.” in the Unreal output log, along with any on-screen functionality you defined in the Blueprints.
Implement a SendFriendInviteByUsername() function that allows players to send friend invites to other players using the player’s full username (display name and discriminator). In a real game, display names will likely be available to a player within a game instances, on leaderboards, or communicated through methods outside of Pragma, such as via voice chat or direct message.
You can fetch your full username using the GetFullUsername() function we defined in the Get party and player information step of the Unreal Party tutorial.
Declare the SendFriendInviteByUsername() function in the public section of your MyPlayerController.h file. Have the function accept a username in the form of a string. This string will include the invitee’s display name (e.g. test01) and discriminator (e.g. #6902)
Define SendFriendInviteByUsername() in your MyPlayerController.cpp file:
voidAMyPlayerController::SendFriendInviteByUsername(constFString&FullUsername){FStringDisplayName,Discriminator;FullUsername.Split("#",&DisplayName,&Discriminator);UPragmaFriendApi::FOnCompleteDelegateSendInviteByDisplayDelegate;SendInviteByDisplayDelegate.BindWeakLambda(this,[DisplayName,Discriminator](TPragmaResult<>Result){if(Result.IsSuccessful()){UE_LOG(LogTemp,Display,TEXT("Sent friend invite to display name: %s"),*DisplayName);}else{UE_LOG(LogTemp,Warning,TEXT("Pragma unable to send friend invite by display name. %s %s %s"),*DisplayName,*Discriminator,*Result.Error().ToString());}});Player->FriendApi().SendFriendInviteByDisplayName(FPragma_Account_DisplayName{DisplayName,Discriminator},SendInviteByDisplayDelegate);}
Our SendFriendInviteByUsername() function accepts a string value representing the invitee’s full username (display name plus discriminator). The function splits the provided username into a DisplayName and a Discriminator so it can send the values as a FPragma_Account_DisplayName object to the GameLoopApi’s SendFriendInviteByDisplayName() function. The GameLoopApi function facilitates sending the friend invite to the correct player.
To test this functionality using the Unreal in-game console, as user test01, issue SendFriendInviteByUsername using the player’s full display name (e.g., test02#7136). You’ll see “You received a friend invite from test01.” in the Unreal output log for user test02.
To test this functionality using Unreal Blueprints:
Create a “Send friend invite by username” button with a editable textbox that accepts a username.
Have the “Send friend invite by username” button call your SendFriendInviteByUsername() method with the entered username.
As user test01, enter another user’s full display name (e.g. test03#1942) in the text box and send the invite.
When successfully executed, you’ll see “You received a friend invite from test01.” in your Unreal output log for user test03, along with any on-screen functionality you defined in the Blueprints.
Implement a SendFriendInviteBySocialId() function that allows players to send friend invites to other players using the player’s social ID. In a real game, this function would likely be called behind the scenes, for example if a player clicks on another player’s avatar in a party to send them a friend invite. In these situations using a social ID is preferable to using a display name because display names can easily change.
You can fetch your social ID using the GetSocialId() function we defined in the Get party and player information step of the Unreal Party tutorial.
Declare the SendFriendInviteBySocialId() function in the public section of your MyPlayerController.h file. Have the function accept a social ID in the form of a string:
Define SendFriendInviteBySocialId() in your MyPlayerController.cpp file:
voidAMyPlayerController::SendFriendInviteBySocialId(constFString&SocialId){UPragmaFriendApi::FOnCompleteDelegateSendInviteBySocialDelegate;SendInviteBySocialDelegate.BindWeakLambda(this,[=,this](TPragmaResult<>Result){if(Result.IsSuccessful()){UE_LOG(LogTemp,Display,TEXT("Sent friend invite to id: %s"),*SocialId);}else{UE_LOG(LogTemp,Warning,TEXT("Pragma unable to send friend invite by ID. %s"),*Result.Error().ToString());}});Player->FriendApi().SendFriendInviteBySocialId(SocialId,SendInviteBySocialDelegate);}
Our SendInviteBySocialId() function accepts a string value representing the invitee’s social ID. Using this ID, the function calls the GameLoopApi’s SendInviteBySocialID() function, which facilitates sending a friend invite to the identified player.
To test this functionality using the Unreal in-game console, as user test01, issue SendInviteBySocialId using the player’s social ID (e.g., test02#7136). You’ll see “You received a friend invite from test01.” in the Unreal output log for user test02.
To test this functionality using Unreal Blueprints:
Using the GetPartyPlayers() function you defined in the Get party and player information step of the Unreal Parties tutorial, display a list of the party members (including their social IDs) in the player’s current party.
Allow a user to click a party player from the list, or create an associated button, to send an invite.
Have your UI action call your SendInviteBySocialId() method with the social ID of the selected player.
As user test01, click a party player’s display name or associated invite button.
When successfully executed, you’ll see “You received a friend invite from test01.” in your Unreal output log for user test03, along with any on-screen functionality you defined in the Blueprints.
Define GetFriendInvites() in your MyPlayerController.cpp file:
TArray<FPragmaFriendOverview>AMyPlayerController::GetFriendInvites(){usingFReceivedInvites=TMap<FString,FPragmaFriendOverview>;FReceivedInvitesPendingReceivedInvites=*Player->FriendApi().GetReceivedInvites();TArray<FPragmaFriendOverview>InviteList;for(auto&PendingFriendInvite:PendingReceivedInvites){FStringPendingFriendSocialId=PendingFriendInvite.Value.SocialId();InviteList.Add(PendingFriendInvite.Value);UE_LOG(LogTemp,Display,TEXT("You have a pending invite from Social ID: %s"),*PendingFriendSocialId);}returnInviteList;}
To test this functionality using the Unreal in-game console, as player 1, send a friend invite to player 2. As player 2, call GetFriendInvites. You’ll see “You have a pending invite from Social ID: " followed by the social ID of player 1.
To test this functionality using Unreal Blueprints, add a “Get friend invites” button and use the returned array to display various friend data, such as display name or social ID.
Implement a AcceptFriendInvite() function and a DeclineInvite() function to allow players to respond to pending friend invites. Players can respond to friend invites using the inviter’s social ID.
Define AcceptFriendInvite() and DeclineInvite() in your MyPlayerController.cpp file:
voidAMyPlayerController::AcceptFriendInvite(constFString&InviterSocialId){UPragmaFriendApi::FOnCompleteDelegateRespondFriendInviteDelegate;RespondFriendInviteDelegate.BindWeakLambda(this,[=,this](TPragmaResult<>Result){if(Result.IsSuccessful()){UE_LOG(LogTemp,Display,TEXT("Accepted friend invite from %s."),*InviterSocialId)}else{UE_LOG(LogTemp,Warning,TEXT("Unable to respond: %s"),*Result.Error().ToString());}});Player->FriendApi().AcceptFriendInvite(InviterSocialId,RespondFriendInviteDelegate);}voidAMyPlayerController::DeclineFriendInvite(constFString&InviterSocialId){UPragmaFriendApi::FOnCompleteDelegateRespondFriendInviteDelegate;RespondFriendInviteDelegate.BindWeakLambda(this,[=,this](TPragmaResult<>Result){if(Result.IsSuccessful()){UE_LOG(LogTemp,Display,TEXT("Declined friend invite from %s."),*InviterSocialId)}else{UE_LOG(LogTemp,Warning,TEXT("Unable to respond: %s"),*Result.Error().ToString());}});Player->FriendApi().DeclineFriendInvite(InviterSocialId,RespondFriendInviteDelegate);}
Our AcceptFriendInvite() and DeclineFriendInvite() functions accepts a string value representing the invite’s social ID, which it uses to call the FriendApi’s AcceptFriendInvite() or DeclineFriendInvite() function. Alternately, you could design one respond function that accepts a boolean value representing whether to accept or decline the friend invite, similar to the accept/decline party invite function (see Accept or decline a party invite).
To test this functionality using the Unreal in-game console:
If you haven’t already, issue a friend request from one player to another (e.g., have test01 send a friend invite to test03#1943).
As test03, view your pending friend invites to see the inviter’s social ID.
Issue AcceptFriendInvite or DeclineFriendInvite with the inviter’s social ID.
If successful, you should see “Accepted friend invite from [test01’s social ID]” or “Declined friend invite from [test01’s social ID]” in the Unreal output log.
To test this functionality using Unreal Blueprints:
Create an editable text box where the player can enter the social ID of the friend who sent the friend invite.
Create an “Accept friend invite” button that calls our AcceptFriendInvite() function with the social ID value entered in the social ID text box.
Create a “Decline friend invite” button that calls our DeclineFriendInvite() function with the social ID value entered in the social ID text box.
When successfully executed, you’ll see “Accepted friend invite from [test01’s social ID]” or “Declined friend invite from [test01’s social ID]” in the Unreal output log along with any on-screen functionality you defined in the Blueprints.
To test this functionality using the Unreal in-game console, as a user with one or more friends, call GetFriends. You’ll see “Friends:” followed by a list of social IDs in the Unreal output log.
To test this functionality using Unreal Blueprints, add a “Get friends” button and use the returned map to display various friend data, such as a list of display names.
To test this functionality using the Unreal in-game console, as a user with one or more friends, call RemoveFriend with a friend’s social ID. You’ll see “Friend removed.” in the Unreal output log.
To test this functionality using Unreal Blueprints, add a “Remove as friend” button next to each friend displayed in the UI. Have the button call your RemoveFriend() function with the social ID of the selected player (Player->SocialID). When successfully executed, you’ll see “Friend removed.” in your Unreal output log, along with any on-screen functionality you defined in the Blueprints, such as updating a list of current friends.
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include"CoreMinimal.h"#include"GameFramework/PlayerController.h"#include"PragmaPtr.h"#include"PragmaGameInstanceSubsystem.h"#include"PragmaResult.h"#include"Dto/PragmaGameInstanceExtDto.h"#include"Dto/PragmaPartyRpcExtDto.h"#include"Pragma/Api/Player/PragmaFriendOverview.h"#include"Pragma/Api/Player/PragmaFriendApi.h"#include"Services/Party/PragmaParty.h"#include"PragmaLocalPlayerSubsystem.h"#include"Pragma/Api/Player/PragmaFriend.h"#include"MyPlayerController.generated.h"// Forward declares Pragma pointer types for Pragma::FPlayer.
PRAGMA_FWD(FPlayer);UCLASS()classUNREALTUTORIAL_APIAMyPlayerController:publicAPlayerController{GENERATED_BODY()public:virtualvoidBeginPlay()override;// Weak pointer to our Pragma Player owned by the PragmaLocalPlayerSubsystem.
Pragma::FRuntimePtrRuntime;Pragma::FPlayerPtrPlayer;//Login and Logout functions
UFUNCTION(Exec,BlueprintCallable,Category="Pragma")voidLogIn(constFString&Username);UFUNCTION(Exec,BlueprintCallable,meta=(Category="Pragma"))voidLogOut();//Initialization functions
UFUNCTION(Exec,BlueprintCallable,Category="Pragma")voidInitializeGameLoop();UFUNCTION(Exec,BlueprintCallable,Category="Pragma")voidInitializeSocial();//Party functions
UFUNCTION(Exec,BlueprintCallable,Category="Pragma")voidCreateParty();UFUNCTION(Exec,BlueprintCallable,Category="Pragma")voidJoinPartyWithCode(constFString&InviteCode);UFUNCTION(Exec,BlueprintCallable,Category="Pragma")voidSendPartyInviteByPlayerId(constFString&InviteeId);UFUNCTION(Exec,BlueprintCallable,meta=(Category="Pragma"))voidRespondToPartyInvite(constFString&PartyInviteId,constboolresponse);UFUNCTION(Exec,BlueprintCallable,Category="Pragma")voidSetGameMode(constEPragma_Party_GameMode&GameModeSelection);UFUNCTION(Exec,BlueprintCallable,meta=(Category="Pragma"))voidSetCharacter(constEPragma_Party_Character&CharacterSelection);UFUNCTION(Exec,BlueprintCallable,meta=(Category="Pragma"))voidLeaveParty();//Matchmaking functions
UFUNCTION(Exec,BlueprintCallable,meta=(Category="Pragma"))voidEnterMatchmaking();//Presence functions
UFUNCTION(Exec,BlueprintCallable,Category="Pragma")voidSetPresenceToOnline();UFUNCTION(Exec,BlueprintCallable,Category="Pragma")voidSetPresenceToAway();UFUNCTION(Exec,BlueprintCallable,Category="Pragma")voidSetInShop(constboolIsInShop);//Friend functions
UFUNCTION(Exec,BlueprintCallable,Category="Pragma")voidSendFriendInviteByUsername(constFString&FullUsername);UFUNCTION(Exec,BlueprintCallable,Category="Pragma")voidSendFriendInviteBySocialId(constFString&SocialId);UFUNCTION(Exec,BlueprintCallable,Category="Pragma")voidAcceptFriendInvite(constFString&InviterSocialId);UFUNCTION(Exec,BlueprintCallable,Category="Pragma")voidDeclineFriendInvite(constFString&InviterSocialId);UFUNCTION(Exec,BlueprintCallable,Category="Pragma")voidRemoveFriend(constFStringFriendSocialID);//Get functions
UFUNCTION(Exec,BlueprintCallable,Category="Pragma")FStringGetFullUsername();UFUNCTION(Exec,BlueprintCallable,meta=(Category="Pragma"))FStringGetPlayerId();UFUNCTION(Exec,BlueprintCallable,Category="Pragma")FStringGetSocialId();UFUNCTION(Exec,BlueprintCallable,Category="Pragma")TArray<FString>GetPartyPlayers();UFUNCTION(Exec,BlueprintCallable,meta=(Category="Pragma"))TArray<FString>GetPartyInvites();UFUNCTION(Exec,BlueprintCallable,meta=(Category="Pragma"))TArray<FPragmaFriendOverview>GetFriendInvites();UFUNCTION(Exec,BlueprintCallable,meta=(Category="Pragma"))TMap<FString,FPragmaFriend>GetFriends();private:voidHandleLoggedIn(constTPragmaResult<>&Result);voidHandleLoggedOut();voidHandleOnPresenceChanged(constFPragmaPresence&MyPresence);voidHandleOnAddedToGame(constFStringGameInstanceId,constFPragma_GameInstance_ExtAddedToGameExt);};
Sample MyPlayerController.cpp source file
// Fill out your copyright notice in the Description page of Project Settings.
#include"MyPlayerController.h"#include"PragmaPlayer.h"#include"Services/Party/PragmaParty.h"#include"Dto/PragmaAccountRpcDto.h"#include"Dto/PragmaPartyRpcExtDto.h"#include"Dto/PragmaPresenceExtDto.h"#include"Pragma/Api/Player/PragmaFriendOverview.h"#include"PragmaLocalPlayerSubsystem.h"voidAMyPlayerController::BeginPlay(){Super::BeginPlay();UE_LOG(LogTemp,Display,TEXT("Initializing"));constauto*Subsystem=GetLocalPlayer()->GetSubsystem<UPragmaLocalPlayerSubsystem>();// The Pragma Runtime is automatically initialized in the PragmaGameInstanceSubsystem.
autoRuntimeA=Subsystem->Runtime();// Set configuration for the SDK before logging in.
RuntimeA->Config().BackendAddress="http://127.0.0.1:10000";RuntimeA->Config().ProtocolType=EPragmaProtocolType::WebSocket;RuntimeA->Config().GameClientVersion="GameServerVersion1";// The UPragmaLocalPlayerSubsystem is automatically initialized
// with a Pragma Player object for every LocalPlayer.
Player=Subsystem->Player();//Event handlers for party actions
Player->PresenceApi().OnPresenceChanged.AddUObject(this,&AMyPlayerController::HandleOnPresenceChanged);Player->GameLoopApi().OnAddedToGame.AddUObject(this,&AMyPlayerController::HandleOnAddedToGame);}//Login and Logout functions
voidAMyPlayerController::LogIn(constFString&Username){Player->LogIn(EPragma_Account_IdProvider::UNSAFE,Username,Pragma::FPlayer::FLoggedInDelegate::CreateUObject(this,&AMyPlayerController::HandleLoggedIn));}voidAMyPlayerController::LogOut(){Player->LogOut(Pragma::FPlayer::FLoggedOutDelegate::CreateUObject(this,&AMyPlayerController::HandleLoggedOut));}//Initialization functions
voidAMyPlayerController::InitializeGameLoop(){UPragmaGameLoopApi::FOnCompleteDelegateGameLoopInitializeDelegate;GameLoopInitializeDelegate.BindWeakLambda(this,[this](constTPragmaResult<>&Result){if(Result.IsSuccessful()){UE_LOG(LogTemp,Display,TEXT("Game loop services initialized."));}else{UE_LOG(LogTemp,Warning,TEXT("Game loop services failed to initialize: %s"),*Result.Error().ToString());}});Player->GameLoopApi().Initialize(GameLoopInitializeDelegate);}voidAMyPlayerController::InitializeSocial(){UPragmaGameLoopApi::FOnCompleteDelegateFriendInitializeDelegate;FriendInitializeDelegate.BindWeakLambda(this,[this](constTPragmaResult<>&Result){if(Result.IsSuccessful()){UE_LOG(LogTemp,Display,TEXT("Friends and Presence services initialized."));}else{UE_LOG(LogTemp,Warning,TEXT("Friends and Presence services failed to initialize: %s"),*Result.Error().ToString());}});Player->FriendApi().Initialize(FriendInitializeDelegate);}//Party functions
voidAMyPlayerController::CreateParty(){UPragmaGameLoopApi::FOnCompleteDelegateOnPartyCreatedDelegate;OnPartyCreatedDelegate.BindWeakLambda(this,[this](TPragmaResult<>Result){if(Result.IsSuccessful()){UE_LOG(LogTemp,Display,TEXT("Pragma party created with code: %s"),*Player->GameLoopApi().GetPartyState()->Party()->GetInviteCode());}else{UE_LOG(LogTemp,Warning,TEXT("Pragma unable to create party: %s"),*Result.Error().ToString());}});Player->GameLoopApi().CreateParty(FPragma_Party_ExtCreateRequest{},FPragma_Party_ExtPlayerJoinRequest{},TArray<FString>(),TMap<FString,int32>(),OnPartyCreatedDelegate);}voidAMyPlayerController::JoinPartyWithCode(constFString&InviteCode){UPragmaGameLoopApi::FOnCompleteDelegateJoinWithInviteCodeDelegate;JoinWithInviteCodeDelegate.BindWeakLambda(this,[=,this](TPragmaResult<>Result){if(Result.IsSuccessful()){UE_LOG(LogTemp,Display,TEXT("Joined party using invite code %s"),*InviteCode);}else{UE_LOG(LogTemp,Warning,TEXT("Unable to join party: %s"),*Result.Error().ToString());}});Player->GameLoopApi().JoinPartyWithInviteCode(FPragma_Party_ExtPlayerJoinRequest{},InviteCode,JoinWithInviteCodeDelegate);}voidAMyPlayerController::SendPartyInviteByPlayerId(constFString&InviteeId){Player->GameLoopApi().SendPartyInvite(InviteeId,UPragmaGameLoopApi::FOnInviteSentDelegate::CreateWeakLambda(this,[this,InviteeId](constTPragmaResult<FString>&SendPartyInviteResult){if(SendPartyInviteResult.IsSuccessful()){constFStringInviteId=SendPartyInviteResult.Payload();UE_LOG(LogTemp,Display,TEXT("Send party invite by player id succeeded. Party invite ID: %s"),*InviteId);}else{UE_LOG(LogTemp,Warning,TEXT("Pragma unable to send invite: %s"),*SendPartyInviteResult.Error().ToString());}}));}TArray<FString>AMyPlayerController::GetPartyInvites(){constTArray<FPragmaPartyInvite>PartyInvites=Player->GameLoopApi().GetPendingPartyInvites();TArray<FString>PartyInviteCodes;for(constFPragmaPartyInvitePartyInvite:PartyInvites){FStringPartyInviteCode=PartyInvite.GetInviteId();UE_LOG(LogTemp,Display,TEXT("Party invite id: %s"),*PartyInviteCode);PartyInviteCodes.Add(PartyInviteCode);}returnPartyInviteCodes;}voidAMyPlayerController::RespondToPartyInvite(constFString&PartyInviteCode,constboolResponse){UPragmaGameLoopApi::FOnCompleteDelegateRespondInviteDelegate;RespondInviteDelegate.BindWeakLambda(this,[=,this](TPragmaResult<>Result){if(Result.IsSuccessful()){if(Response==true){UE_LOG(LogTemp,Display,TEXT("Accepted party invite id %s. Party successfully joined."),*PartyInviteCode);}else{UE_LOG(LogTemp,Display,TEXT("Declined party invite id %s"),*PartyInviteCode);}}else{UE_LOG(LogTemp,Warning,TEXT("Unable to respond: %s"),*Result.Error().ToString());}});Player->GameLoopApi().RespondToPartyInvite(FPragma_Party_ExtPlayerJoinRequest{},PartyInviteCode,Response,RespondInviteDelegate);}voidAMyPlayerController::SetGameMode(constEPragma_Party_GameMode&GameModeSelection){if(Player->GameLoopApi().IsLeaderOfParty(Player->Id())==true){FPragma_Party_ExtUpdatePartyRequestRequest;Request.Update.SetNewGameMode(GameModeSelection);UPragmaGameLoopApi::FOnCompleteDelegateUpdatePartyDelegate;UpdatePartyDelegate.BindWeakLambda(this,[=,this](TPragmaResult<>Result){if(Result.IsSuccessful()){UE_LOG(LogTemp,Display,TEXT("Changed game mode selection to %s"),*UEnum::GetValueAsString<EPragma_Party_GameMode>(GameModeSelection));}else{UE_LOG(LogTemp,Warning,TEXT("Unable to change game mode: %s"),*Result.Error().ToString());}});Player->GameLoopApi().UpdateParty(Request,UpdatePartyDelegate);}else{UE_LOG(LogTemp,Display,TEXT("Only party leaders can select game mode"));}}voidAMyPlayerController::SetCharacter(constEPragma_Party_Character&CharacterSelection){UPragmaGameLoopApi::FOnCompleteDelegateUpdatePartyPlayerDelegate;UpdatePartyPlayerDelegate.BindWeakLambda(this,[=,this](TPragmaResult<>Result){if(Result.IsSuccessful()){UE_LOG(LogTemp,Display,TEXT("Changed character selection to %s"),*UEnum::GetValueAsString<EPragma_Party_Character>(CharacterSelection));}else{UE_LOG(LogTemp,Warning,TEXT("Unable to change character: %s"),*Result.Error().ToString());}});FPragma_Party_ExtUpdatePartyPlayerRequestRequest;Request.Update.SetNewCharacter(CharacterSelection);Player->GameLoopApi().UpdatePartyPlayer(Request,UpdatePartyPlayerDelegate);}voidAMyPlayerController::LeaveParty(){UPragmaGameLoopApi::FOnCompleteDelegateLeavePartyDelegate;LeavePartyDelegate.BindWeakLambda(this,[this](TPragmaResult<>Result){if(Result.IsSuccessful()){UE_LOG(LogTemp,Display,TEXT("Successfully left party."));}else{UE_LOG(LogTemp,Warning,TEXT("Unable to leave party: %s"),*Result.Error().ToString());}});Player->GameLoopApi().LeaveParty(LeavePartyDelegate);}//Matchmaking functions
voidAMyPlayerController::EnterMatchmaking(){UPragmaGameLoopApi::FOnCompleteDelegateOnEnterMatchmakingDelegate;OnEnterMatchmakingDelegate.BindWeakLambda(this,[this](TPragmaResult<>Result){if(Result.IsSuccessful()){UE_LOG(LogTemp,Display,TEXT("Enter matchmaking success."));}else{UE_LOG(LogTemp,Warning,TEXT("Pragma unable to enter matchmaking: %s"),*Result.Error().ToString());}});Player->GameLoopApi().EnterMatchmaking(OnEnterMatchmakingDelegate);}//Presence functions
voidAMyPlayerController::SetPresenceToOnline(){Player->PresenceApi().SetAsOnline(UPragmaPresenceApi::FOnCompleteDelegate::CreateWeakLambda(this,[](constTPragmaResult<>&Result){if(Result.IsSuccessful()){UE_LOG(LogTemp,Display,TEXT("Set presence to online succeeded."));}else{UE_LOG(LogTemp,Display,TEXT("Set presence to online failed."));}}));}voidAMyPlayerController::SetPresenceToAway(){Player->PresenceApi().SetAsAway(UPragmaPresenceApi::FOnCompleteDelegate::CreateWeakLambda(this,[](constTPragmaResult<>&Result){if(Result.IsSuccessful()){UE_LOG(LogTemp,Display,TEXT("Set presence to away succeeded."));}else{UE_LOG(LogTemp,Display,TEXT("Set presence to away failed."));}}));}voidAMyPlayerController::SetInShop(constboolIsInShop){FPragma_Presence_ExtRichPresencePlayerRequestRequest;Request.Update.SetInShop(IsInShop);UPragmaPresenceApi::FOnCompleteDelegateSetRichPresenceDelegate;SetRichPresenceDelegate.BindWeakLambda(this,[IsInShop](TPragmaResult<>Result){if(Result.IsSuccessful()){UE_LOG(LogTemp,Display,TEXT("Set in shop to %s"),IsInShop?TEXT("true"):TEXT("false"));}else{UE_LOG(LogTemp,Warning,TEXT("Unable to set rich presence: %s"),*Result.Error().ToString());}});Player->PresenceApi().SetRichPresence(Request,SetRichPresenceDelegate);}// Friend functions
voidAMyPlayerController::SendFriendInviteByUsername(constFString&FullUsername){FStringDisplayName,Discriminator;FullUsername.Split("#",&DisplayName,&Discriminator);UPragmaFriendApi::FOnCompleteDelegateSendInviteByDisplayDelegate;SendInviteByDisplayDelegate.BindWeakLambda(this,[DisplayName,Discriminator](TPragmaResult<>Result){if(Result.IsSuccessful()){UE_LOG(LogTemp,Display,TEXT("Sent friend invite to display name: %s"),*DisplayName);}else{UE_LOG(LogTemp,Warning,TEXT("Pragma unable to send friend invite by display name. %s %s %s"),*DisplayName,*Discriminator,*Result.Error().ToString());}});Player->FriendApi().SendFriendInviteByDisplayName(FPragma_Account_DisplayName{DisplayName,Discriminator},SendInviteByDisplayDelegate);}voidAMyPlayerController::SendFriendInviteBySocialId(constFString&SocialId){UPragmaFriendApi::FOnCompleteDelegateSendInviteBySocialDelegate;SendInviteBySocialDelegate.BindWeakLambda(this,[=,this](TPragmaResult<>Result){if(Result.IsSuccessful()){UE_LOG(LogTemp,Display,TEXT("Sent friend invite to id: %s"),*SocialId);}else{UE_LOG(LogTemp,Warning,TEXT("Pragma unable to send friend invite by ID. %s"),*Result.Error().ToString());}});Player->FriendApi().SendFriendInviteBySocialId(SocialId,SendInviteBySocialDelegate);}voidAMyPlayerController::AcceptFriendInvite(constFString&InviterSocialId){UPragmaFriendApi::FOnCompleteDelegateRespondFriendInviteDelegate;RespondFriendInviteDelegate.BindWeakLambda(this,[=,this](TPragmaResult<>Result){if(Result.IsSuccessful()){UE_LOG(LogTemp,Display,TEXT("Accepted friend invite from %s."),*InviterSocialId)}else{UE_LOG(LogTemp,Warning,TEXT("Unable to respond: %s"),*Result.Error().ToString());}});Player->FriendApi().AcceptFriendInvite(InviterSocialId,RespondFriendInviteDelegate);}voidAMyPlayerController::DeclineFriendInvite(constFString&InviterSocialId){UPragmaFriendApi::FOnCompleteDelegateRespondFriendInviteDelegate;RespondFriendInviteDelegate.BindWeakLambda(this,[=,this](TPragmaResult<>Result){if(Result.IsSuccessful()){UE_LOG(LogTemp,Display,TEXT("Declined friend invite from %s."),*InviterSocialId)}else{UE_LOG(LogTemp,Warning,TEXT("Unable to respond: %s"),*Result.Error().ToString());}});Player->FriendApi().DeclineFriendInvite(InviterSocialId,RespondFriendInviteDelegate);}voidAMyPlayerController::RemoveFriend(constFStringFriendSocialID){UPragmaFriendApi::FOnCompleteDelegateRespondRemoveFriendDelegate;RespondRemoveFriendDelegate.BindWeakLambda(this,[=,this](TPragmaResult<>Result){if(Result.IsSuccessful()){UE_LOG(LogTemp,Display,TEXT("Removed friend: %s."),*FriendSocialID)}else{UE_LOG(LogTemp,Warning,TEXT("Unable to remove friend: %s"),*Result.Error().ToString());}});Player->FriendApi().RemoveFriend(FriendSocialID,RespondRemoveFriendDelegate);}//Handler functions
voidAMyPlayerController::HandleLoggedIn(constTPragmaResult<>&Result){if(Result.IsFailure()){UE_LOG(LogTemp,Display,TEXT("Pragma -- Login failed: %s"),*Result.ErrorCode());return;}UE_LOG(LogTemp,Display,TEXT("Pragma -- Logged in."));}voidAMyPlayerController::HandleLoggedOut(){UE_LOG(LogTemp,Display,TEXT("Pragma -- Logged out."));}voidAMyPlayerController::HandleOnAddedToGame(constFStringGameInstanceId,constFPragma_GameInstance_ExtAddedToGameExt){UE_LOG(LogTemp,Display,TEXT("Game instance ID: %s"),*GameInstanceId);}voidAMyPlayerController::HandleOnPresenceChanged(constFPragmaPresence&MyPresence){UE_LOG(LogTemp,Display,TEXT("Presence status changed: ""\n Basic: %s, \n Rich: %s, %s"),*UEnum::GetValueAsString<EBasicPresence>(MyPresence.BasicPresence),MyPresence.Ext.InShop?TEXT("In shop"):TEXT("Not in shop"),MyPresence.Ext.InParty?TEXT("In party"):TEXT("Not in party"));}//Get functions
//Get player's username (display name and discriminator)
FStringAMyPlayerController::GetFullUsername(){UE_LOG(LogTemp,Display,TEXT("Your full username: %s"),*Player->FullDisplayName());returnPlayer->FullDisplayName();}//Get player's UUID
FStringAMyPlayerController::GetPlayerId(){UE_LOG(LogTemp,Display,TEXT("Your player ID: %s"),*Player->Id());returnPlayer->Id();}FStringAMyPlayerController::GetSocialId(){UE_LOG(LogTemp,Display,TEXT("Your social ID: %s"),*Player->SocialId());returnPlayer->SocialId();}//Get list of player objects for players in the party
TArray<FString>AMyPlayerController::GetPartyPlayers(){constTArray<constUPragmaPartyPlayer*>PartyPlayers=Player->GameLoopApi().GetPartyState()->Party()->GetPlayers();TArray<FString>DisplayNames;constFString&YourPlayerId=Player->Id();for(constUPragmaPartyPlayer*PartyPlayer:PartyPlayers){FStringDisplayName=PartyPlayer->GetDisplayName().DisplayName;FStringPlayerId=PartyPlayer->GetPlayerId();FStringSocialId=PartyPlayer->GetSocialId();if(PlayerId==YourPlayerId){DisplayName+=" (You)";}if(PartyPlayer->IsLeader()){DisplayName+=" (Leader)";}if(PartyPlayer->IsReady()){DisplayName+=" (Ready)";}DisplayNames.Add(DisplayName);UE_LOG(LogTemp,Display,TEXT("Display name: %s, Player ID: %s, Social ID: %s"),*DisplayName,*PlayerId,*SocialId);}returnDisplayNames;}//Get list of pending friend invites
TArray<FPragmaFriendOverview>AMyPlayerController::GetFriendInvites(){usingFReceivedInvites=TMap<FString,FPragmaFriendOverview>;FReceivedInvitesPendingReceivedInvites=*Player->FriendApi().GetReceivedInvites();TArray<FPragmaFriendOverview>InviteList;for(auto&PendingFriendInvite:PendingReceivedInvites){FStringPendingFriendSocialId=PendingFriendInvite.Value.SocialId();InviteList.Add(PendingFriendInvite.Value);UE_LOG(LogTemp,Display,TEXT("You have a pending invite from Social ID: %s"),*PendingFriendSocialId);}returnInviteList;}//Get list of friends
TMap<FString,FPragmaFriend>AMyPlayerController::GetFriends(){TMap<FString,FPragmaFriend>MyFriendList=*Player->FriendApi().GetFriends();UE_LOG(LogTemp,Display,TEXT("Friends: "));for(auto&MyFriend:MyFriendList){UE_LOG(LogTemp,Display,TEXT("%s"),*MyFriend.Key);}returnMyFriendList;}
Congratulations! You now have a custom Unreal implementation of the Pragma Engine Friend service. Read our Friend service docs to learn about more features you can apply to your game.
We use cookies to analyze our traffic. We also share information about your use of our site with our analytics partners who may combine it with other information that you’ve provided to them or that they’ve collected from your use of their services.