How can I get my own PlayerController on my Listen server?

I know it’s an old question, but I had encoutered the same kind of issue. So I’ll to explain 2-3 things.

You have to separate two things : Controller ID and Controller Index.

The index is the position in the world player controller’s array. It may change for the same controller especially in a Listen Server after a seamless travel with a controller swap (ex : if changing the class).

The ID (indentifier) of the controller is store in the LocalPlayer and is unique for each local controller, where 0 is the “main” controller that can be used for referencing HUD & Widgets.

So " the controller on index 0 is always "your player controller" " is not true.
If you need the main controller, you have to add a little C++ function like so :

APlayerController* UMyClass::GetMainController(const UObject* WorldContextObject)
{
	// Get world context (containing player controllers)
	if (UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull))
	{
		// Loop on player controllers
		for (FConstPlayerControllerIterator Iterator = World->GetPlayerControllerIterator(); Iterator; ++Iterator)
		{
			// Get player controller from iterator
			APlayerController* PlayerController = Iterator->Get();

			// Get local player if exist
			ULocalPlayer* LocalPlayer = PlayerController->GetLocalPlayer();

			// If it's local and id is 0, it's the main controller
			if (LocalPlayer != nullptr && LocalPlayer->GetControllerId() == 0)
			{
				return PlayerController;
			}
		}
	}

	// Not found
	return nullptr;
}

Hope it’ll help some other devs !

2 Likes