I found the problem after some hours of debugging. Player State didn’t get initialize or replicated or available at the time I try to bind the input action because of late join and haven’t received a valid player state
if (PlayerState* M_PlayerState = Cast<S_PlayerState>(PlayerState))
{
EnhancedInputComponent->BindAction(InputTargetActorConfirm, ETriggerEvent::Triggered, S_PlayerState->GetAbilitySystemComponent(), &UAbilitySystemComponent::InputConfirm);
EnhancedInputComponent->BindAction(InputTargetActorCancel, ETriggerEvent::Triggered, S_PlayerState->GetAbilitySystemComponent(), &UAbilitySystemComponent::InputCancel);
}
So I just remove the If check and bind them to these function instead
EnhancedInputComponent->BindAction(InputTargetActorConfirm, ETriggerEvent::Triggered, this, &S_PlayerController::TryConfirmAbility);
EnhancedInputComponent->BindAction(InputTargetActorCancel, ETriggerEvent::Triggered, this, &S_PlayerController::TryCancelAbility);
And these function do
void S_PlayerController::TryConfirmAbility()
{
if (S_PlayerState* M_PlayerState = Cast<S_PlayerState>(PlayerState))
{
M_PlayerState->ConfirmInput();
}
}
void S_PlayerController::TryCancelAbility()
{
if (S_PlayerState* M_PlayerState = Cast<S_PlayerState>(PlayerState))
{
M_PlayerState->CancelInput();
}
}