Problem with Enhanced Input and Split Screen on UE 5.1

I’m having a problem with using two game pads for a split screen game using enhanced input in UE 5.1.
I manually spawn player characters in my project but I used third-person templates to test this problem as well.
I’m having trouble getting my game pads to work with it, they won’t get assigned automatically like before and getting a reference ID to “Enhanced Input Local Player Subsystem” node only work on player 0 and both my game pads control player 0. Even getting a controller reference from create local player to it only works for player 0.
I’ve been wondering if anyone has a proper way of setting it up.
Like no matter what controller id I get to the Enhanced input node for mapping it either doesn’t for neither players or all game pads only control player 0 at the same time.
Thank you in advanced.

2 Likes

@Gixo
Is there any way you could provide screenshots of your blueprint setup?
-Zen

So I have two gamepads hooked up and both of them are working and navigate the editor’s viewport. As I play the game only keyboard and my first gamepad are injecting input and changing “Skip Assigning Gamepad to Player 1” option won’t make any difference.
In the first image my keyboard and my first gamepad control player 0 or don’t work at all.
On the second one I made a custom controller blueprint and I was able to directly input movement to only player 1 but I don’t think that would be a scalable solution.
Also I have tried to disable default pawn class and manually create players and spawning them and posses them by controllers and get a reference from it to “Enhance Input Local Player Subsystem” node by a player controller variable on the spawn but it didn’t work.
My gamepads work fine on UE 5.0.3 with the old input system.


I updated to 5.1 a few days ago and have the exact same issue. Everything was fine before but all of a sudden any Gamepad that isn’t the first one, is not recognized by the game anymore.

Update: Just realized that the sample game Lyra also has a local multiplayer included. And it’s working in there. So I guess looking into that makes sense. I don’t have the time tonight, but If I find an answer I’ll make a new reply here.

1 Like

I found what I was looking for. The lyra project uses this to spawn its players. I don’t know why, yet, but using CreateLocalPlayerForPlatformUser (instead of CreateLocalPlayer) works for me. All I can say is, that GetAllActiveUsers retrieves a map of plugged-in devices, which is already useful.

Hope that helps you and others out there, too!

2 Likes

Thank you for your reply.
Unfortunately it’s not working for me, it behaves the same as before and I tested it on default template to be sure as well.
The weird thing I noticed is that when I check spawn players as spectators in game mode each controller moves the cameras as it should.
“Skip Assigning Gamepad to Player 1” is not working as well.

Alright after a lot of work into this as i was facing the issue too

The get controller variable takes time to spawn in, the fix is really easy

simply add a delay before you call the cast controller method
image
(the Create Controls is just a macro i made for the creation event, its just copied from third person and unchanged)

5 Likes

Thank you!

Thanks a lot for finding a solution!

For anyone who’s having this issue adding a delay node before “Cast To Player Controller” in player’s blueprint only worked for me in combination with Caviarail’s Solution and not the single “Create Local Player” node.
Also “Skip Assigning Gamepad to Player 1” still doesn’t do anything for me.

1 Like

Could you show me more details? I can’t figure out what needs to be changed.

I assume it’s in BP_ThirPersonCharacter

1 Like

Yeah, like wtf is their problem!!!

Hopefully this helps:

Hi ! Thanks for the help !
Unfortunately, in my case, “Get All Active Users” returns a list of only 1 entry. Therefore, it does not create a second player, event though my gamepad is connected (is I can move the player 1 with it)

3 Likes

The first physical controller will always bind to the first PlayerController, together with mouse and keyboard. There is a setting in the project settings to bind the first controller to the 2nd PlayerController, but for me it never worked and 1st physical controller always binds to 1st PlayerController, setting checked or not. So you would need a 2nd physical controller to test and control a 2nd PlayerController

1 Like

Thanks for this ! This work fine for me but I got another issue, I can spawn an infinite number of player, do you have any idea where it come from ?

1 Like

Nevermind, I just forgot to plug the return value from my spawn actor node to the “In Pawn” Possess node and now I just came back to my previous error which is : I can’t spawn two player because my keyboard and my controller can both move my character, so thanks anyway

EDIT : The node “Get All Active Players” always return user id 0 and number of active platform users 1, so I believe there is an error from here

2 Likes

Yeah, I think it might be a bug or something that the “skip assigning gamepad to player 1” used to work in previous versions of UE and now is not working in 5.1.x.
The fix only works for two gamepads. Keyboard and the first gamepad controlled the first player no matter what I did.

Does anyone have any documentation on the new PlatformUserIds? I am guessing that they are meant to replace the LocalControllerId but it would be nice to be sure. I have written some C++ functions to access the InternalId of the PlatformUserId to use that instead of the LocalControllerId for identifying the local players in my game. But I would really like to know if I am using it the way it’s intended :smiley:

Hi, thanks for the update. On my side the second controller is never detected, like I can spawn my first player with the first controller I connected (physically) to the computer but the second one can’t do anything.
Does someone know if I might have missed something ?

I was trying to get the Enhanced Input system to work with C++ and local multiplayer. I had the same problem where the player was created and splitscreen worked but no input was being accepted to the second player. Thank you for discovering that a delay was necessary.

Here’s some tips if you’re trying to do this in C++.
In your Game Mode BeginPlay function create the player like normal:

APlayerController* NewController = UGameplayStatics::CreatePlayer(GetWorld(), 1, true);

This works just fine if you have enough Player Start actors in the world.

Now in your player character you have to wait some time after begin play, you can do this in two ways, create a timer and a callback in your header:

FTimerHandle BindInputsTimer;

UFUNCTION()
void BindInputs();

And in your implementation execute the timer with the callback in BeginPlay:

void AMyCharacter::BeginPlay()
{
    // Call the base class
    Super::BeginPlay();

    if (GetWorld())
    {
        GetWorld()->GetTimerManager().SetTimer(BindInputsTimer, this, &AMyCharacter::BindInputs, 0.2f);
    }
}

void AMyCharacter::BindInputs()
{
    //Add Input Mapping Context
    if (APlayerController* PlayerController = Cast<APlayerController>(Controller))
    {
        if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
        {
            Subsystem->AddMappingContext(DefaultMappingContext, 0);
        }
    }
}

I would not consider this good practice though. I’m pretty sure you only have to wait a single frame for the Enhanced Input system to become available, so it might be better to just check if the the mapping context has been set in Tick and set it if not, then you don’t need a timer and on the first tick the context will be set.

void AMyCharacter::Tick(float DeltaTime)
{
    //Add Input Mapping Context
    if (APlayerController* PlayerController = Cast<APlayerController>(Controller))
    {
        if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
        {
            if (!Subsystem->HasMappingContext(DefaultMappingContext))
            {
                Subsystem->AddMappingContext(DefaultMappingContext, 0);
            }
        }
    }
}

This isn’t really good practice either, but I can’t find a place in the actor lifecycle that’s after BeginPlay and before Tick where the Enhance Input system is available.

Also Skip Assigning Gamepad to Player 1 does not work for me either.

1 Like