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.