This post is part 5 of mmo character creation series.
- Overview for character creation
- Dealing with complex nested options
- Applying the options to skeletal mesh (using n-hance assets)
- Connect character creation to custom server
- Populate character selection screen from server (this post)
In the last post we’ve looked at creating characters via API.
In this chapter we want to start getting the account characters populated for the user.
Therefore, in this post, we want to be embedding this API call into our UE project and parsing the details to render our characters.
It’s important that the payload is matched between create character
and select character
screen. i.e., we’re going to be reusing a lot of blueprints which are evaluating the actors meshes/materials. It will be clearer when we start the implementation.
Make the character selection screen first
If you’re following from previous chapters, you may want the character selection screen to be the first one you see when you open the game now.
This is quite trivial to do, open up your HUD (Heads up display) blueprint, mine is called CharacterCreateHUD
and simply change the widget that’s first displayed from character creation to select character widget.
Select character widget blueprints
The majority of work in this post will be for the Select character widget
. In the previous post we’ve just created a skeleton widget for it. I will cover those steps again as they’re small.
First, create a widget called Select Character Widget
, of User Widget
class.
You can do this by right click -> user interface -> widget blueprint
.
Design it as you like, this is my design:
For reference, I used these assets by HONETi – 2D Assets for the designs.
I also covered blueprints for the Create character
button.
This simply opens up the widget for create character, and closes this one off.
Ok now we’ve caught up – let’s look at the new additions.
Spawning actor to represent your character
Very similar to create character screen, we want to spawn the actor to represent our selected character.
Therefore, we may as well copy that function over to this blueprint! It was called Spawn male character
in the create character widget. Here’s what we’re creating anyway, its fairly small:
I added the Enable Input
and Set Actor as Hidden in game
too.
Ok let’s look at the constructor and destructor now for this widget.
Ok so on the constructor we want to spawn the character mesh actor that will represent our character then we want to fetch characters. If we have no characters to display, no problem because we can keep the actor hidden.
On the destructor, simply destroy the actor.
Getting characters from server
For fetching the characters, I created new graph, ApiComms
graph. Here I added a new custom event
to FetchCharacters
.
This is using VaRest to GET account characters from the server, here’s the Postman request example.
We can see the request is fairly simple, making sure we set the request as GET
request, content type does not matter as we’re not setting a body for the request. Then we populate the header with the account name, which at the moment is static.
After we apply the URL, we want to be collecting the data to be ready for processing.
Ok so from above blueprint, we need to understand the following:
- what is the account characters struct?
- what is the helper
convert to account character response
doing - what is
re draw selected options
doing
Account characters struct
This struct should reflect whatever output is from the server, that you care about.
i.e. example of my response from server is:
{
"accountCharacters": [
{
"name": "someTest1",
"accountName": "testAcc1",
"appearanceInfo": {
"hairStyle": "h_m_style_1",
"race": "human",
"gender": "m",
"skinColor": "h_m_style_1",
"facialFeature": "feature_1",
"hairColor": "color1"
},
"updatedAt": "2022-10-03T15:33:00.214Z",
"isOnline": false
}
]
}
Ok so from the above, I want to capture all the details under accountCharacters
.
I can see [
which means it will be array, so I know I will have an array of Account characters
struct.
Inside the array is an object containing:
- name (character name)
- accountName
- appearanceInfo
- updatedAt
- isOnline
I don’t care about updatedAt
or isOnline
at this stage, so will ignore them.
name
and accountName
are pure strings.
appearanceInfo
has the same structure as AppearanceInfo
struct that we used before (in create character request) so we don’t need to create that now. Here it is for reference.
Ok so now we know all the pieces that want to go inside the new structure, so let’s make it:
With this struct, we can now capture all the details from our API and have them in an easy to use form.
Convert to account character response
Now that the structure is ready, we want to be taking the JSON from our API call and converting it to the array of account characters.
To help with this I created a new blueprint for holiding function libraries:
We will be creating 2 functions here.
- JSON to character appearance struct
- JSON to account characters
Name them as you like, my first one is: ConvertToCharacterAppearance
:
The function call is relatively simple.
Have a look at the input/output for the function; input is Va Rest Json Object
and output is Character Appearance
.
So, you can simply create a Character Appearance
struct and start populating all the fields which are taken from JSON. All of them are string fields, so for each one you can do Get String Field
and just specify the name of the field. You can cross reference the names from the Postman response and/or documentation.
Next, we look at ConvertToAccountCharacterResponse
function:
As described above, there’s 3 fields we care about:
- name
- accountName
- appearanceInfo
name
and accountName
are simple string fields, so we can fetch them using Get String Field
call.
For appearanceInfo
, this is a nested object, so we Get Object Field
with this name and use the ConvertToAccountCharacterResponse
function to get this struct. We create the AccountCharacter
struct using all this data and return.
Re-draw selected options – Toggle Character widget
Ok now we have all the data we need to start populating the select character screen – we have an array of Account Character
structs, which contain the name of the characters and the appearance information.
We will use this to draw buttons to choose the character and render the actor on the screen.
Before we go into the specific blueprints of this, let’s introduce the widget which will show the character name and allow you to click it in order to change selected character.
It’s a fairly simple widget, containing just the character name at this stage.
Just make sure the text block is set to Is Variable
, which will allow us to set string dynamically.
For the blueprints you will want to do the following:
- add account character as public editable variable
- create an event dispatcher, for when a button is clicked
- populate the textbox with character name
- add onClicked event for button, when clicked call the dispatcher
For the event dispatcher, you will want to edit the Inputs
and add the Account Character
as input here.
This means that when the dispatcher is called, it will provide the selected account character
along with the event, which is very useful.
Re-draw selected options – Blueprints
Ok so now we created a widget for Toggle Character
. This widget is used to display the buttons for each of the character that’s present.
Let’s create a variable to hold all these button widgets:
And this is the implementation:
Ok when we call to re-draw the select options, we will first clear the widget list, if it’s not empty for whatever reason.
This is not fully necessary as we plan to destroy this entire widget when we toggle between create/select character. But its good practice, because you may choose to hide widgets instead of destroying and anything that can be repopulated should be cleaned.
Ok now that you cleaned the toggle widgets array, we want to iterate over the Account Characters
array obtained from the API and create the Toggle Character Widget
for each of the present account characters struct. We add a little padding to it dynamically here, but may not be necessary depending on your design.
The Toggle Charactewr Widget
takes in the Account Character
struct which is how it knows what name to render on the screen.
We add the widget to the Scroll Box
component in the Select Character Widget
using Add Child
method.
For each of the added Select Character Widget
components – which is effectively a button to select your character, we want to bind the Event to Character Selected
.
This event returns the Account character
struct, which is great. We can now create a local variable for Selected Character
and once set, we can create a custom event to Render Selected Character
.
Note that at the end of ReDrawSelectOptions
(on Completed
call of the For Each Loop
function) we also Render First Character
. This is just to display the first character in the list, when available.
The blueprints for that are:
Ok so what do we have:
- Render first character will check if populated
Account characters
is present or not- if not present, it will ensure the actor is hidden
- if present, it will set the
selected character
to first one in the list, and ask to render it
- Render selected character will obtain the
Appearance Struct
from theAccount Character
struct and ask the Skeletal Mesh (Actor) blueprint to resolve the appearance based on this
In this re-rendering, we’re reusing 100% of the logic created part of create character
logic, which was covered in chapter 22 – apply options to mesh – if you don’t have this logic implemented, do check that post about how its achieved.
The results
Ok so let’s make a ‘new account’ by modifying the header values in the API calls.
Now we can go to ‘Create character’ and create new character
Let’s create testCharacter1
character.
We’ll get taken back to character selection screen with this character now available.
Let’s create a new character, testCharacter2
.
Ok great, we’re now basically ready to start implementing the button for Login
and getting the player into the game!
There are obviously additional validations that are missing that you may want to include, for example – what’s the character limit? What about character name, are numerical characters allowed?