Skip to content

Commit ca9872f

Browse files
committed
Document widget binding
1 parent 696ed26 commit ca9872f

10 files changed

Lines changed: 407 additions & 0 deletions

File tree

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
---
2+
title: Bind friends and party members to UMG widgets
3+
description: Simplify your implementation of friend and party lists in your game using UMG widget binding.
4+
---
5+
6+
import Blueprint from "@site/src/Blueprint";
7+
import Video from "@site/src/Video";
8+
9+
import bpListEntryEvent from "./bind_friends_list/list_entry_event.bp";
10+
import bpListEntryCast from "./bind_friends_list/list_entry_cast.bp";
11+
import bpListBind from "./bind_friends_list/list_bind.bp";
12+
import bpActionCheck from "./bind_friends_list/action_check.bp";
13+
import bpActionPerform from "./bind_friends_list/action_perform.bp";
14+
import bpAccessExternal1 from "./bind_friends_list/access_external_1.bp";
15+
import bpAccessExternal2 from "./bind_friends_list/access_external_2.bp";
16+
import videoPreview from "./bind_friends_list/preview.mp4";
17+
18+
Traditionally to display friend lists or list of party members in-game, you had to listen for events and manually synchronise the player list when things changed.
19+
20+
EOS Online Framework now provides **widget binding**: you tell the plugin that you want the list of friends and/or party members synchronised to a UMG tree view widget, and the plugin automatically keeps the item list up-to-date. This allows you to focus on the design and layout of player lists, and eliminates manual synchronisation code.
21+
22+
## Widget binding in the example project
23+
24+
We've used widget binding to [implement the friend list in the example project](../example_project.mdx). This is what it looks like:
25+
26+
<Video url={videoPreview} />
27+
28+
## Prerequisites
29+
30+
Before you use widget binding, you'll need a few things:
31+
32+
- A widget blueprint that contains a `TreeView` widget you want to display friends and/or party members under.
33+
- A list entry widget blueprint that implements the `User Object List Entry` interface.
34+
35+
## Implementing the list entry widget
36+
37+
The list entry widget that implements `User Object List Entry` needs to implement the `On List Item Object Set` event. This is the event that the tree view will call when the friend or section heading associated with this list entry changes.
38+
39+
UMG does not re-create list entry widgets when the list changes; it instead re-uses them and calls `On List Item Object Set` when the list entry needs to represent a different value.
40+
41+
### Store the list item object in a variable
42+
43+
You'll want to create a variable on your list entry widget that can be used to store the `List Item Object` received from `On List Item Object Set` when it's called. You can then use this variable later when you want to retrieve things like the player name.
44+
45+
<Blueprint height="200px" blueprint={bpListEntryEvent} />
46+
47+
### Detect the type of list entry
48+
49+
List entry widgets can be assigned two different types of objects, depending on what they're meant to represent:
50+
51+
- `RedpointFriendListEntry`: This represents a friend or party member in the list.
52+
- `RedpointFriendListSection`: This represents a section of the list, such as "In-Party", "In-Game", "Online" or "Offline".
53+
54+
To check whether the list entry widget has been assigned one of these types, you should cast the variable you stored the `List Item Object` in. For example, this is how you could implement a "Get Player Display Name" function for rendering the player's name:
55+
56+
<Blueprint height="300px" blueprint={bpListEntryCast} />
57+
58+
## Bind the friend and party list to the tree view
59+
60+
In your widget blueprint that contains the UMG tree view, call "Bind Friend List Sections to Tree View Widget" with the list of sections you want included:
61+
62+
<Blueprint height="600px" blueprint={bpListBind} />
63+
64+
You can call "Bind Friend List Sections to Tree View Widget" again later if you want to change the displayed sections. If you want to stop synchronising friend list sections to the tree view widget entirely, you can call "Unbind Friend List Sections from Tree View Widget".
65+
66+
## Available friend list entry data
67+
68+
Friend list entries provide the following information as variables or functions on the `RedpointFriendListEntry` object:
69+
70+
- `bHasGameProfile`: If true, this user has a game profile and the `UserId` property will be filled with a valid user ID. The local user may have friends from the local platform who have never played this game before, in which case the `UserId` property will not have a valid user ID set.
71+
- `UserId`: The user ID.
72+
- `DisplayName`: The user's display name.
73+
- `bInParty`: This user is in the local player's current party.
74+
- `bIsInvitable`: If true, this user can be invited to parties or games via EOS or the local platform.
75+
- `InviteStatus`: The user's invite status, and how they are related to the local player.
76+
- `PresenceStatus`: The user's presence status.
77+
- `bPlayingThisGame`: If true, this user is currently playing this game.
78+
- `bIsGameFriend`: If true, this user is a friend only at the game level, and not from the platform.
79+
- `bIsBeingActedUpon`: If true, the local player is currently [performing some kind of action on this friend](#acting-on-friend-list-entries) (such as inviting them to the party). This boolean value can be used to disable UI elements when the user is already doing something or to show an operation as in-progress.
80+
- `bInJoinableParty`: If the user is currently in a party that the local player can join.
81+
- `GetSectionType()`: Returns the section type that this entry should be displayed under.
82+
83+
## Acting on friend list entries
84+
85+
If you want to provide a list of actions that the user can take for a friend list entry, the plugin provides all the functions you should need:
86+
87+
| Check if action can be performed | Perform action |
88+
| -------------------------------- | --------------------------------------------- |
89+
| Can Invite to Party | Invite Friend List Entry to Party |
90+
| Can Kick from Party | Kick Friend List Entry from Party |
91+
| Can Promote to Party Leader | Promote Friend List Entry to Party Leader |
92+
| Can Send Friend Request | Send Friend Request to Friend List Entry |
93+
| Can Block Player | Block Friend List Entry |
94+
| Can Unblock Player | Unblock Friend List Entry |
95+
| Can Remove Friend | Remove Friend referenced by Friend List Entry |
96+
| Can Accept Friend Request | Accept Friend Request from Friend List Entry |
97+
| Can Reject Friend Request | Reject Friend Request from Friend List Entry |
98+
| Can Join Party | Join Party of Friend List Entry |
99+
| Can Leave Party | Leave Party of Friend List Entry |
100+
101+
:::note
102+
"Join Game of Friend List Entry" will be added in a future release.
103+
:::
104+
105+
### Check if an action can be performed
106+
107+
To see whether an action can be performed, use the appropriate "Check if action can be performed" function listed above on the friend list entry object:
108+
109+
<Blueprint height="220px" blueprint={bpActionCheck} />
110+
111+
### Perform an action on a friend list entry
112+
113+
To perform an action on a friend list entry, use the appropriate "Perform action" function listed above.
114+
115+
:::warning
116+
Perform functions must be called from the blueprint event graph, since they are asynchronous. You can't call them inside blueprint functions.
117+
:::
118+
119+
<Blueprint height="220px" blueprint={bpActionPerform} />
120+
121+
## Get the friend list entry object outside the list entry widget
122+
123+
You can access the current selected item on the tree view through `Get Selected Item`:
124+
125+
<Blueprint height="220px" blueprint={bpAccessExternal1} />
126+
127+
Alternatively, you can store last selected friend entry when the `On Item Selection Changed` event fires:
128+
129+
<Blueprint height="240px" blueprint={bpAccessExternal2} />
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
Begin Object Class=/Script/BlueprintGraph.K2Node_VariableGet Name="K2Node_VariableGet_3" ExportPath="/Script/BlueprintGraph.K2Node_VariableGet'/Game/Redpoint/MainMenu/Screens/Lobby/W_FriendList.W_FriendList:EventGraph.K2Node_VariableGet_3'"
2+
VariableReference=(MemberName="FriendTreeView",MemberGuid=E4816D779A66309086341FD2FAECB28D,bSelfContext=True)
3+
NodePosX=2144
4+
NodePosY=2677
5+
NodeGuid=2299CF11429546F8007BBB96D3C81367
6+
CustomProperties Pin (PinId=393FDEFD4CB27764E400D6BC5CCF510A,PinName="FriendTreeView",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/UMG.TreeView'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_9 2AEF290B4A91BA9F66254CBA66C5F260,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
7+
CustomProperties Pin (PinId=7EFF6D9248CEF1B5B7FD86B47E529898,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/UMG.WidgetBlueprintGeneratedClass'/Game/Redpoint/MainMenu/Screens/Lobby/W_FriendList.W_FriendList_C'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
8+
End Object
9+
Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_9" ExportPath="/Script/BlueprintGraph.K2Node_CallFunction'/Game/Redpoint/MainMenu/Screens/Lobby/W_FriendList.W_FriendList:EventGraph.K2Node_CallFunction_9'"
10+
bDefaultsToPureFunc=True
11+
FunctionReference=(MemberParent="/Script/CoreUObject.Class'/Script/UMG.ListView'",MemberName="BP_GetSelectedItem")
12+
NodePosX=2336
13+
NodePosY=2639
14+
NodeGuid=02802CA043B353466DDFE791DA8429AA
15+
CustomProperties Pin (PinId=2AEF290B4A91BA9F66254CBA66C5F260,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nList View Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/UMG.ListView'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_VariableGet_3 393FDEFD4CB27764E400D6BC5CCF510A,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
16+
CustomProperties Pin (PinId=22DF0F2E47612CE2297346941FD9648A,PinName="ReturnValue",PinToolTip="Return Value\nObject Reference\n\nGets the first selected item, if any; recommended that you only use this for single selection lists.",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/CoreUObject.Object'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_DynamicCast_4 991885B14495621D9D1FEF93C313A0B8,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
17+
End Object
18+
Begin Object Class=/Script/BlueprintGraph.K2Node_DynamicCast Name="K2Node_DynamicCast_4" ExportPath="/Script/BlueprintGraph.K2Node_DynamicCast'/Game/Redpoint/MainMenu/Screens/Lobby/W_FriendList.W_FriendList:EventGraph.K2Node_DynamicCast_4'"
19+
TargetType="/Script/CoreUObject.Class'/Script/RedpointEOSFramework.RedpointFriendListEntry'"
20+
NodePosX=2592
21+
NodePosY=2623
22+
NodeGuid=5331241B4DEFEFB865FA95934846867F
23+
CustomProperties Pin (PinId=B967992A41D3213A22E2BF9D2ABA4A9F,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
24+
CustomProperties Pin (PinId=C81663EB4E2C3ED189A9CE9DC9AEA35C,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
25+
CustomProperties Pin (PinId=D3D68B494B972037997FBB852CBE777B,PinName="CastFailed",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
26+
CustomProperties Pin (PinId=991885B14495621D9D1FEF93C313A0B8,PinName="Object",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/CoreUObject.Object'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_9 22DF0F2E47612CE2297346941FD9648A,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
27+
CustomProperties Pin (PinId=1C7CFCAA4876F9322710218103FBFA13,PinName="AsRedpoint Friend List Entry",Direction="EGPD_Output",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/RedpointEOSFramework.RedpointFriendListEntry'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_CallFunction_10 A8B35DF44CF0C9C277E17AAC5F822941,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
28+
CustomProperties Pin (PinId=23EB524F46CE854490E55083D962F924,PinName="bSuccess",Direction="EGPD_Output",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
29+
End Object
30+
Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_10" ExportPath="/Script/BlueprintGraph.K2Node_CallFunction'/Game/Redpoint/MainMenu/Screens/Lobby/W_FriendList.W_FriendList:EventGraph.K2Node_CallFunction_10'"
31+
bDefaultsToPureFunc=True
32+
FunctionReference=(MemberParent="/Script/CoreUObject.Class'/Script/RedpointEOSFramework.RedpointFriendListEntry'",MemberName="CanInviteToParty")
33+
NodePosX=2928
34+
NodePosY=2671
35+
NodeGuid=9CEC98704BCCF3D6844E69B35D6EFF18
36+
CustomProperties Pin (PinId=A8B35DF44CF0C9C277E17AAC5F822941,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nRedpoint Friend List Entry Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/RedpointEOSFramework.RedpointFriendListEntry'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_DynamicCast_4 1C7CFCAA4876F9322710218103FBFA13,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
37+
CustomProperties Pin (PinId=30C9A61344EB9FCCD779198FFDF72F1F,PinName="ReturnValue",PinToolTip="Return Value\nBoolean\n\nIf true, the local player can invite this person to the party.",Direction="EGPD_Output",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="false",AutogeneratedDefaultValue="false",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
38+
End Object

0 commit comments

Comments
 (0)