Hey guys, first time posting here, long time lurker and I started my UE journey about 2 years ago, started practicing with Blueprints to get the basics and worked my way to C++. Currently I am working on an RPG with GAS and Action Bars (Like WoW, where you can assign abilities to the Action Bar and then you can keybind the buttons to trigger actions).
I am using two Mapping Input Contexts, one for controller where the Action Bar and other inputs are handled and a Character IMC that handles movement and everything works perfectly in single player. Action Bar implementation with GAS works great, but I have an odd issue when running the project in multiplayer. The inputs implemented in the Controller C++ class are being ignored; I have debugged with verbose log and definitely the inputs are not being detected and the methods are not being run. But if I go to the Blueprint version of the same controller and add the “AI_ActionBarButton1” and call my C++ methods, works without any issues on multiplayer. Also, clicking on the button works just fine, which confirms that the method is functional. Now, I could just go ahead and implement this part through blueprints, but as I am still learning, I just want to figure out what is the issue here because this is driving me crazy. Here’s a screenshot of the Blueprint:
if(UEnhancedInputLocalPlayerSubsystem * Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer()))
{
Subsystem->AddMappingContext(ControllerMappingContext, 0);
}
if (UEnhancedInputComponent* EnhancedInputComponent = Cast<UEnhancedInputComponent>(InputComponent))
{
EnhancedInputComponent->BindAction(ActionBarButton1Action, ETriggerEvent::Started, this, &ANUNAWorldDefaultController::PressActionBarButton1);
EnhancedInputComponent->BindAction(ActionBarButton1Action, ETriggerEvent::Triggered, this, &ANUNAWorldDefaultController::HoldActionBarButton1);
EnhancedInputComponent->BindAction(ActionBarButton1Action, ETriggerEvent::Completed, this, &ANUNAWorldDefaultController::ReleaseActionBarButton1);
This works fine in single player and validated that there are any issues here, as for my implementation, I tried to do a RPC as the simple implementation didn’t work:
void ANUNAWorldDefaultController::PressActionBarButton1(const FInputActionValue& Value)
{
UE_LOG(LogTemp, Warning, TEXT("PressActionBarButton1 triggered."));
if (IsLocalController())
{
UE_LOG(LogTemp, Warning, TEXT("PressActionBarButton1: Local controller detected."));
ServerHandlePressActionBarButton1();
}
else
{
UE_LOG(LogTemp, Warning, TEXT("PressActionBarButton1: Not a local controller."));
}
}
bool ANUNAWorldDefaultController::ServerHandlePressActionBarButton1_Validate()
{
UE_LOG(LogTemp, Warning, TEXT("ServerHandlePressActionBarButton1 validated."));
return true;
}
void ANUNAWorldDefaultController::ServerHandlePressActionBarButton1_Implementation()
{
UE_LOG(LogTemp, Warning, TEXT("ServerHandlePressActionBarButton1_Implementation called."));
UNUNAContentSlot* ContentSlot = GetContentSlotFromActionBar(1);
if (ContentSlot)
{
UE_LOG(LogTemp, Warning, TEXT("ServerHandlePressActionBarButton1: Content slot found. Handling button press."));
ContentSlot->HandleButtonPressed();
}
else
{
UE_LOG(LogTemp, Warning, TEXT("ServerHandlePressActionBarButton1: No content slot found for action bar 1."));
}
}
void ANUNAWorldDefaultController::HoldActionBarButton1(const FInputActionValue& Value)
{
UE_LOG(LogTemp, Warning, TEXT("HoldActionBarButton1 triggered."));
if (IsLocalController())
{
UE_LOG(LogTemp, Warning, TEXT("HoldActionBarButton1: Local controller detected."));
ServerHandleHoldActionBarButton1();
}
else
{
UE_LOG(LogTemp, Warning, TEXT("HoldActionBarButton1: Not a local controller."));
}
}
bool ANUNAWorldDefaultController::ServerHandleHoldActionBarButton1_Validate()
{
UE_LOG(LogTemp, Warning, TEXT("ServerHandleHoldActionBarButton1 validated."));
return true;
}
void ANUNAWorldDefaultController::ServerHandleHoldActionBarButton1_Implementation()
{
UE_LOG(LogTemp, Warning, TEXT("ServerHandleHoldActionBarButton1_Implementation called."));
UNUNAContentSlot* ContentSlot = GetContentSlotFromActionBar(1);
if (ContentSlot)
{
UE_LOG(LogTemp, Warning, TEXT("ServerHandleHoldActionBarButton1: Content slot found."));
//ContentSlot->HandleButtonHeld();
}
else
{
UE_LOG(LogTemp, Warning, TEXT("ServerHandleHoldActionBarButton1: No content slot found for action bar 1."));
}
}
void ANUNAWorldDefaultController::ReleaseActionBarButton1(const FInputActionValue& Value)
{
UE_LOG(LogTemp, Warning, TEXT("ReleaseActionBarButton1 triggered."));
if (IsLocalController())
{
UE_LOG(LogTemp, Warning, TEXT("ReleaseActionBarButton1: Local controller detected."));
ServerHandleReleaseActionBarButton1();
}
else
{
UE_LOG(LogTemp, Warning, TEXT("ReleaseActionBarButton1: Not a local controller."));
}
}
bool ANUNAWorldDefaultController::ServerHandleReleaseActionBarButton1_Validate()
{
UE_LOG(LogTemp, Warning, TEXT("ServerHandleReleaseActionBarButton1 validated."));
return true;
}
void ANUNAWorldDefaultController::ServerHandleReleaseActionBarButton1_Implementation()
{
UE_LOG(LogTemp, Warning, TEXT("ServerHandleReleaseActionBarButton1_Implementation called."));
UNUNAContentSlot* ContentSlot = GetContentSlotFromActionBar(1);
if (ContentSlot)
{
UE_LOG(LogTemp, Warning, TEXT("ServerHandleReleaseActionBarButton1: Content slot found. Handling button release."));
ContentSlot->HandleButtonReleased();
}
else
{
UE_LOG(LogTemp, Warning, TEXT("ServerHandleReleaseActionBarButton1: No content slot found for action bar 1."));
}
}
All functions are declared and defined and works fine in single player, but not in multiplayer, I don’t get any of the LOG warnings. Adding the server functions just in case:
// Function called when an action bar button is pressed
void PressActionBarButton1(const FInputActionValue& Value);
// Server function to handle the action bar button press
UFUNCTION(Server, Reliable, WithValidation)
void ServerHandlePressActionBarButton1();
bool ServerHandlePressActionBarButton1_Validate();
void ServerHandlePressActionBarButton1_Implementation();
// Function called when an action bar button is held
void HoldActionBarButton1(const FInputActionValue& Value);
// Server function to handle the action bar button hold
UFUNCTION(Server, Reliable, WithValidation)
void ServerHandleHoldActionBarButton1();
bool ServerHandleHoldActionBarButton1_Validate();
void ServerHandleHoldActionBarButton1_Implementation();
// Function called when an action bar button is released
void ReleaseActionBarButton1(const FInputActionValue& Value);
// Server function to handle the action bar button release
UFUNCTION(Server, Reliable, WithValidation)
void ServerHandleReleaseActionBarButton1();
bool ServerHandleReleaseActionBarButton1_Validate();
void ServerHandleReleaseActionBarButton1_Implementation();
Is there any reason or am I missing something here why the input for the controller through C++ is getting ignored in multiplayer?
Thanks in advance!!