Join game directly or via invite

For some reason no games are listed for my test partner. No idea why. Might be different region. Anyway, I figured “Why not simply implement joining the game directly?”

I still don’t quite understand why it works the way it does. The options are named quite confusingly. For instance inviting works just fine even though I set bAllowInvite to false. But anyway.
For anyone who’s interested, here is what you need to add to make joining directly (via Shift+Tab in-game and then right clicking the player you want to join/invite):

Creating the session:

    FOnlineSessionSettings Settings;

	Settings.bIsLANMatch = false;
	Settings.NumPublicConnections = 2;
	Settings.bShouldAdvertise = true;
	Settings.bUsesPresence = true;
	Settings.bUseLobbiesIfAvailable = true;
	Settings.bAllowInvites = false;
	Settings.bAllowJoinViaPresence = true;
	Settings.bAllowJoinInProgress = true;

	SessionInterface->CreateSession(0, SessionName, Settings);

Declaring the join/invite callbacks in the game instance header:

virtual void OnSessionInviteReceived(const FUniqueNetId& UserId, const FUniqueNetId& FromId, const FString& AppId, const FOnlineSessionSearchResult& OnlineSessionSearchResult);
virtual void OnSessionUserInviteAccepted(bool bWasSuccessful, int ControllerId, TSharedPtr<const FUniqueNetId, ESPMode::Fast> UserId, const FOnlineSessionSearchResult& OnlineSessionSearchResult);

Implementing the methods in the game instance cpp:

void UPuzzlePlatformsGameInstance::OnSessionInviteReceived(
	const FUniqueNetId& UserId,
	const FUniqueNetId& FromId,
	const FString& AppId,
	const FOnlineSessionSearchResult& OnlineSessionSearchResult
)
{
	UEngine* Engine = GetEngine();
	if (!ensureMsgf(Engine != nullptr, TEXT("Engine was NULL"))) return;
	if (!ensureMsgf(SessionInterface.IsValid(), TEXT("SessionInterface not ready"))) return;

	Engine->AddOnScreenDebugMessage(-1, 30, FColor::Yellow, FString::Printf(TEXT("Session invite received: '%s'"), *AppId));

	if (SessionInterface->JoinSession(0, NewSessionName, OnlineSessionSearchResult))
	{
		Engine->AddOnScreenDebugMessage(-1, 30, FColor::Blue, FString::Printf(TEXT("Joining session...")));
	}
	else
	{
		Engine->AddOnScreenDebugMessage(-1, 30, FColor::Red, FString::Printf(TEXT("Could not join session")));
	}
}

void UPuzzlePlatformsGameInstance::OnSessionUserInviteAccepted(
	bool bWasSuccessful,
	int ControllerId,
	TSharedPtr<const FUniqueNetId, ESPMode::Fast> UserId,
	const FOnlineSessionSearchResult& OnlineSessionSearchResult
)
{
	UEngine* Engine = GetEngine();
	if (!ensureMsgf(Engine != nullptr, TEXT("Engine was NULL"))) return;
	if (!ensureMsgf(SessionInterface.IsValid(), TEXT("SessionInterface not ready"))) return;

	if (bWasSuccessful)
	{
		Engine->AddOnScreenDebugMessage(-1, 30, FColor::Blue, FString::Printf(TEXT("Session invite accepted successfully")));
	}
	else
	{
		Engine->AddOnScreenDebugMessage(-1, 30, FColor::Red, FString::Printf(TEXT("Session invite not accepted")));
	}

	if (SessionInterface->JoinSession(0, NewSessionName, OnlineSessionSearchResult))
	{
		Engine->AddOnScreenDebugMessage(-1, 30, FColor::Blue, FString::Printf(TEXT("Joining session...")));
	}
	else
	{
		Engine->AddOnScreenDebugMessage(-1, 30, FColor::Red, FString::Printf(TEXT("Could not join session")));
	}
}

And of course adding the delegates in Init():

SessionInterface->OnSessionInviteReceivedDelegates.AddUObject(this, &UPuzzlePlatformsGameInstance::OnSessionInviteReceived);
SessionInterface->OnSessionUserInviteAcceptedDelegates.AddUObject(this, &UPuzzlePlatformsGameInstance::OnSessionUserInviteAccepted);

Works for me!

1 Like

Thanks for sharing this.

Privacy & Terms