C++ and Widget Blueprint for ServerList

Hi.

I followed this Wiki article written by @eXi

He provides this function** to be used in Blueprints**:

The problem is, when I call this function in my Widget Blueprint (for the server list) I’m only saying “Ok, search for sessions”

The function that really gives me the result of the Find process is OnFindSessionsComplete (which has no connection with blueprints!)

Now, what the Widget Blueprint needs to do is basically two things:

  1. **WAIT **for the OnFindSessionsComplete to finish
  2. **GET **the various settings (ServerName, GameMode, PlayersConnected, MaxPlayers, Ping)

Any ideas about how to get this done?

When it comes to make C++ and Blueprints communicate, my brain just wraps up…

Thanks in advance!

Create a AsyncNode and bind one delegate exec pin to the OnFindSessionsComplete event.

That pin will execute when OnFindSessionsComplete is fired.

Mhm… and what can I do with it? I mean… I don’t need an event that fires when OnFindSessionComplete executes

I need OnFindSessionComplete to call a Widget event when the SearchResult is ready

Below the implementation of OnFindSessionComplete


void UPAGameInstance::OnFindSessionsComplete(bool bWasSuccessful)
{
    IOnlineSubsystem* const OnlineSub = IOnlineSubsystem::Get();
    if (OnlineSub)
    {
        IOnlineSessionPtr Sessions = OnlineSub->GetSessionInterface();
        if (Sessions.IsValid())
        {
            Sessions->ClearOnFindSessionsCompleteDelegate_Handle(OnFindSessionsCompleteDelegateHandle);

            if (SessionSearch->SearchResults.Num() > 0)
            {
                // "SessionSearch->SearchResults" is an Array that contains all the information. You can access the Session in this and get a lot of information.
                // This can be customized later on with your own classes to add more information that can be set and displayed
                for (int32 SearchIdx = 0; SearchIdx < SessionSearch->SearchResults.Num(); SearchIdx++)
                {                    

                    GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("Session Number: %d | Sessionname: %s "), SearchIdx + 1, *(SessionSearch->SearchResults[SearchIdx].Session.OwningUserName)));
                }
            }

            else
            {
                // No sessions found...
            }
        }
    }
}

Simply create a function that get’s called when OnFindSessionsComplete is fired that passes it the SearchResults array, you can then process these in UMG however you want, like clearing then populating a list of sessions.

Ok we’re close.

What you said already came to my mind but the problem is always the same: making C++ and Blueprints communicate.

Say I create a function in my Game Instance



TArray<FOnlineSessionSearchResult> SessionSearchResultReady(const TArray<FOnlineSessionSearchResult>& searchResults)
{

}


Then? I need to create a child blueprint for my Game Instance? Ok, let’s say I make it…

The first error is that Blueprints don’t support arrays of FOnlineSessionSearchResult

So I’m forced to create a wrapper struct containing all the basic info of a **FOnlineSessionSearchResult **and use that in my function argument?


All this sounds crazy, I’m looking for something that isn’t a workaround… workarounds are very often warning signs

I understand the frustration. What you are looking for is a native type, FBlueprintSessionResult, that should do the trick for you. It’s just a small wrapper that contains an FOnlineSessionSearchResult. To be even cleaner, you can extend UUserWidget and setup the delegate so that your UMG widget only has to ask for sessions and can bind to it’s callback directly, to get the array of session results right in the widget. No need to work around the game instance.

Most small projects avoid the trouble by using the Advanced Sessions plugin, which blueprints many other interactions and types for you.

Ok! Even closer!

The Game Instance blueprint now has the event **SessionSearchResultReady **which receives all the sessions found (array of FBlueprintSessionResult).

NOW, I need to pass this array to the Widget so that the Widget can loop throught it and for each one create a child-row in the user interface.

How do I pass this array from GameInstance (blueprint) to Widget blueprint?

Do I need to create a function in the Widget blueprint and call it from GameInstance blueprint passing the array? But the problem is: how do I reference the Widget from the GameInstance blueprint?

What a headache

My goal is to use C++ entirely for networking… but it feels like the Engine developers wanted to push these stupid blueprints
Not to talk about significant leak of documentation

Grab the ShooterGame example. It’s the best documentation you can hope for (and you can pull apart all the C++ networking, menus, etc).

– Zak Parrish, Epic Games

I assumed you were using Unreal Motion Graphics for the UI part, if you are the standard convention is to pass widgets data they then use in their event graph to do things like populate lists, etc. All the networking can be and generally is handled in C++. ShooterGame is an excellent example but unfortunately uses Slate which you likely don’t want.

I think what you are looking to do is have your UUserWidget, which would be the parent class of your UMG widget in the editor, grab a reference to your GameInstance, ask it to search for some sessions and bind its OnFindSessionsComplete delegate to its own function, then it can handle the results within itself by passing a populated TArray of FBlueprintSessionResult’s to one of its events that you bind to in the widget. Then in the widgets graph you just have the event hooked up for whenever it gets called to populate your list or what have you with server widgets.

There is an issue with the sessions.

At the end I decided to get a reference to the Widget in the GameInstance, not viceversa.

The issue is that when I host a session (i’m using Steam Online Subsystem) I use my steam username

But when I find for sessions I get strange behaviours

  1. The found ServerName isn’t “gedamial”

  2. There are three of them? O.o

  3. There are 0 people in the session… but then it shouldn’t be a session at all…

This is the function that is called inside the Widget as soon as the GameInstance provides the sessions:

**ServerInfo **is a variable of type **BlueprintSessionResult **that will be used to display the session properties (servername, ping, players…)

Any idea?

I can successfully host sessions but I am unable to find sessions… it always finds me 0 sessions available.

Is this because I’m using the same computer / **steam **account ?

If yes, how am I supposed to test my game since I am ONE developer?

Just want to notify everyone: That Wiki Article mentioned in the first post is outdated as hell. I can’t edit it cause Epic locked the Wiki months ago and aren’t really doing anything properly with it…

Which is ridiculous, since that is the only valid C++/Networking documentation ever written… feels like Epic Games kindly aims to discourage the use of C++ for pushing Blueprints.

.

By the way, if anyone knows the answer, i’ll quote myself:

Sounds like a fun conspiracy theory!

UE4 changes often, which is why documentation tends to go out of date rather quickly. While Epic tries very hard to keep documentation updated, it inevitably falls behind the curve. The one source you can guarantee to be up-to-date is the samples. Like I said before, open up ShooterGame, go through it. Toss in breakpoints, read the code. It’s the best source.

As far as I’m aware, you cannot find host sessions from the same PC using the same steam account. You need two PCs. For testing replication in general, you can just do two PIE sessions via the Editor. When you absolutely have to test Steam features, you’ll need a buddy or another PC to help.