Unreal: Friends #
This tutorial uses Unreal Engine 5.3 with Pragma Engine 0.4.0 to demonstrate integrating Pragma Engine friend 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.
Get DisplayName and SocialId #
Goal: Get your full display name and social ID to use when testing friend functionality.
In
MyPlayerController.h
, declareGetFullUsername()
andGetSocialId()
:UFUNCTION(Exec, BlueprintCallable, Category="Pragma") FString GetFullUsername(); UFUNCTION(Exec, BlueprintCallable, Category="Pragma") FString GetSocialId();
In
MyPlayerController.cpp
, defineGetFullUsername()
andGetSocialId()
:FString AMyPlayerController::GetFullUsername() { UE_LOG(LogTemp, Display, TEXT("MyGameClient -- Your full username: %s"), *Player->FullDisplayName()); return Player->FullDisplayName(); } FString AMyPlayerController::GetSocialId() { UE_LOG(LogTemp, Display, TEXT("MyGameClient -- Your social ID: %s"), *Player->SocialId()); return Player->SocialId(); }
Test #
To test this functionality using the Unreal in-game console, issue GetFullUsername
and GetSocialId
for test01
and test02
. Record these values to use in later steps.
Send friend invite by username #
Goal: Allow 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.
Steps #
In
MyPlayerController.h
, declareSendFriendInviteByUsername()
. 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
)public: UFUNCTION(Exec, BlueprintCallable, Category="Pragma") void SendFriendInviteByUsername(const FString& FullUsername);
In
MyPlayerController.cpp
, defineSendFriendInviteByUsername()
:void AMyPlayerController::SendFriendInviteByUsername(const FString& FullUsername) { FString DisplayName, Discriminator; FullUsername.Split("#", &DisplayName, &Discriminator); Player->FriendApi().SendFriendInviteByDisplayName( FPragma_Account_DisplayName{DisplayName, Discriminator}, UPragmaFriendApi::FOnCompleteDelegate::CreateWeakLambda( this, [DisplayName, Discriminator](const TPragmaResult<> Result) { if (Result.IsSuccessful()) { UE_LOG(LogTemp, Display, TEXT("MyGameClient -- Sent friend invite to display name: %s"), *DisplayName); } else { UE_LOG(LogTemp, Error, TEXT( "MyGameClient -- Unable to send friend invite by display name. %s %s %s" ), *DisplayName, *Discriminator, *Result.GetErrorAsString()); } })); }
Our SendFriendInviteByUsername()
method 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 FriendApi’s SendFriendInviteByDisplayName()
method. The FriendApi method facilitates sending the friend invite to the correct player.
Test #
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.
Send friend invite by social ID #
Goal: Allow players to send friend invites to other players using the player’s social ID
In a real game, the SendFriendInviteBySocialId()
method 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.
Steps #
In
MyPlayerController.h
, declareSendFriendInviteBySocialId()
. Have the function accept a social ID in the form of a string:public: UFUNCTION(Exec, BlueprintCallable, Category="Pragma") void SendFriendInviteBySocialId(const FString& SocialId);
In
MyPlayerController.cpp
, defineSendFriendInviteBySocialId()
:void AMyPlayerController::SendFriendInviteBySocialId(const FString& SocialId) { Player->FriendApi().SendFriendInviteBySocialId( SocialId, UPragmaFriendApi::FOnCompleteDelegate::CreateWeakLambda( this, [this, SocialId](const TPragmaResult<> Result) { if (Result.IsSuccessful()) { UE_LOG(LogTemp, Display, TEXT("MyGameClient -- Sent friend invite to id: %s"), *SocialId); } else { UE_LOG(LogTemp, Error, TEXT("MyGameClient -- Unable to send friend invite by ID. %s"), *Result.GetErrorAsString()); } })); }
Our SendInviteBySocialId()
method accepts a string value representing the invitee’s social ID. Using this ID, the function calls the FriendApi’s SendInviteBySocialID()
method, which facilitates sending a friend invite to the identified player.
Test #
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:
- Display a list of the party members (including their social IDs) in the player’s current party. You can get a list of party players via the
FPragmaParty
GetPlayers()
method. - Allow a user to click a party player from the list to send them a friend 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.
View pending friend invites #
Goal: Allows users to retrieve a list of pending received friend invitations.
Steps #
In
MyPlayerController.h
, declare theGetFriendInvites()
:public: UFUNCTION(Exec, BlueprintCallable, meta=(Category="Pragma")) TArray<FPragmaFriendOverview> GetFriendInvites();
In
MyPlayerController.cpp
, defineGetFriendInvites()
:TArray<FPragmaFriendOverview> AMyPlayerController::GetFriendInvites() { using FReceivedInvites = TMap<FString, FPragmaFriendOverview>; FReceivedInvites PendingReceivedInvites = *Player->FriendApi().GetReceivedInvites(); TArray<FPragmaFriendOverview> InviteList; for (auto&PendingFriendInvite : PendingReceivedInvites) { FString PendingFriendSocialId = PendingFriendInvite.Value.SocialId(); InviteList.Add(PendingFriendInvite.Value); UE_LOG(LogTemp, Display, TEXT("You have a pending invite from Social ID: %s"), *PendingFriendSocialId); } return InviteList; }
Test #
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.
Accept or decline a friend invite #
Goal: Allow players to accept or decline a friend invite.
Players can respond to friend invites using the inviter’s social ID.
Steps #
In
MyPlayerController.h
, declareAcceptFriendInvite()
andDeclineInvite()
:public: UFUNCTION(Exec, BlueprintCallable, Category="Pragma") void AcceptFriendInvite(const FString& InviterSocialId); UFUNCTION(Exec, BlueprintCallable, Category="Pragma") void DeclineFriendInvite(const FString& InviterSocialId);
In
MyPlayerController.cpp
, defineAcceptFriendInvite()
andDeclineInvite()
:void AMyPlayerController::AcceptFriendInvite(const FString& InviterSocialId) { Player->FriendApi().AcceptFriendInvite( InviterSocialId, UPragmaFriendApi::FOnCompleteDelegate::CreateWeakLambda( this, [this, InviterSocialId](const TPragmaResult<> Result) { if (Result.IsSuccessful()) { UE_LOG(LogTemp, Display, TEXT("MyGameClient -- Accepted friend invite from %s."), *InviterSocialId) } else { UE_LOG(LogTemp, Error, TEXT("MyGameClient -- Unable to accept friend invite: %s"), *Result.GetErrorAsString()); } })); } void AMyPlayerController::DeclineFriendInvite(const FString& InviterSocialId) { Player->FriendApi().DeclineFriendInvite( InviterSocialId, UPragmaFriendApi::FOnCompleteDelegate::CreateWeakLambda( this, [this, InviterSocialId](const TPragmaResult<> Result) { if (Result.IsSuccessful()) { UE_LOG(LogTemp, Display, TEXT("MyGameClient -- Declined friend invite from %s."), *InviterSocialId) } else { UE_LOG(LogTemp, Error, TEXT("MyGameClient -- Unable to decine friend invite: %s"), *Result.GetErrorAsString()); } })); }
Our AcceptFriendInvite()
and DeclineFriendInvite()
functions accept a string value representing the invite’s social ID, which it uses to call the FriendApi’s AcceptFriendInvite()
or DeclineFriendInvite()
function.
Test #
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 totest03#1943
). - As
test03
, view your pending friend invites to see the inviter’s social ID. - Issue
AcceptFriendInvite
orDeclineFriendInvite
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.
Get Friend list #
Goal: Allow users to retrieve a list of players on their friend list, identified by social ID.
Steps #
In
MyPlayerController.h
, declareGetFriends()
:public: UFUNCTION(Exec, BlueprintCallable, meta=(Category="Pragma")) TMap<FString, FPragmaFriend> GetFriends();
In
MyPlayerController.cpp
, defineGetFriends()
: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); } return MyFriendList; }
Test #
To test this functionality using the Unreal in-game console, as a user with one or more friends, issue 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.
Remove a friend #
Goal: Allow players to remove another player from their friends list, using the friend’s social ID.
Steps #
In
MyPlayerController.h
, declareRemoveFriend()
:public: UFUNCTION(Exec, BlueprintCallable, Category="Pragma") void RemoveFriend(const FString FriendSocialID);
In
MyPlayerController.cpp
, defineRemoveFriend()
:void AMyPlayerController::RemoveFriend(const FString FriendSocialID) { Player->FriendApi().RemoveFriend( FriendSocialID, UPragmaFriendApi::FOnCompleteDelegate::CreateWeakLambda( this, [this, FriendSocialID](const TPragmaResult<> Result) { if (Result.IsSuccessful()) { UE_LOG(LogTemp, Display, TEXT("MyGameClient -- Removed friend: %s."), *FriendSocialID) } else { UE_LOG(LogTemp, Error, TEXT("MyGameClient -- Unable to remove friend: %s"), *Result.GetErrorAsString()); } })); }
Test #
To test this functionality using the Unreal in-game console, as a user with one or more friends, issue 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.
Next steps #
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.