Please help with the Enhanced Input for the controller! The usual setup of the Input is officially labeled as deprecated. I do everything according to the instructions and everything works, but only for ACharacter, and for the APlayerController does not work. I use UE5.2 Will be very grateful if you help.
For the APlayerController code does not work, on the line marked red throws an runtime error, the program crashes:
I have the same settings, apparently this is not the case.
did this project start as a C++ project or a blueprint project? was this a project that was started on a version before 5.2?
make sure that for the file invoking calls to UEnhancedInputComponent that it is in scope: #include "EnhnacedInputSubsystems.h"
is in either the .h or the .cpp
what is the specific error that the crash report gives?
The project is built on C + + UE5.2, I have not run it on other versions of UE.
I rewrote the code but got no result, I will now rewrite the example and give more details. Thank you for responding!
If you post code, please post it using quoted code blocks, not as screen shots.
Screen shots don’t render particularly legible on many devices.
OK
EnhanPlayerController.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "EnhanPlayerController.generated.h"
UCLASS()
class ABZ_API AEnhanPlayerController : public APlayerController
{
GENERATED_BODY()
public:
/** MappingContext */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
class UInputMappingContext* DefaultMappingContext;
/** ControllerAction Input Action */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
class UInputAction* ControllerAction;
protected:
// APawn interface
virtual void SetupInputComponent() override;
// To add mapping context
virtual void BeginPlay();
/** Called for ControllerAction input */
void ControllerActionMethod();
};
EnhanPlayerController.cpp
#include "EnhanPlayerController.h"
#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"
void AEnhanPlayerController::SetupInputComponent()
{
// Set up action bindings
if (UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(InputComponent))
{
EnhancedInputComponent->BindAction(ControllerAction, ETriggerEvent::Triggered, this, &AEnhanPlayerController::ControllerActionMethod);
}
}
void AEnhanPlayerController::BeginPlay()
{
Super::BeginPlay();
//Add Input Mapping Context
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer()))
{
Subsystem->AddMappingContext(DefaultMappingContext, 0);
}
}
void AEnhanPlayerController::ControllerActionMethod()
{
GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Black, TEXT("AEnhanPlayerController::ControllerActionMethod()"));
}
to get code blocks
Like this
which can have multiple line breaks
is 3x Tilde (the button commonly to the left of 1 often called “Grave”) on the line before and the line after the text a single one will highlight the text
when the editor crashes what is the top line of the report (you can also find this by going to the Saved/Logs/[ProjectName].log will be the most recent one. there the crash report is at the bottom.
ОК
is there any particular reason that you need the enhanced Input Component code to be segregated out of the Character class, and placed on a derived Controller class?
Yes, there is functionality associated with managing multiple characters and pawns. I think the controller is the perfect place to do this because it’s not convenient to store this functionality in a single character. The first version of my code worked exactly like this, but there were problems when switching to UE5.2.
Fair enough I guess worst case you could take a look at the TopDown Template, or make a fake character that just so happens to communicate with and manage the other characters, but on to the issue at hand.
I might be blind right now
but where is the InputComponent
that you are using on the line:
if (UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(InputComponent))
defined or assigned to? is this supposed to be an editor assignment, or is this a member in another class?
InputComponent is defined in Actor.h and is public. The controller is inherited from the actor. With normal input this pointer can be used, but apparently does not work with enhanced input. I don’t know how to do it for enhanced input - it’s just a guess…
The idea with a fictitious character is interesting Can you explain in more detail?
I am going to put this in the context of a Real Time Strategy, but could be applied to most systems, so I am presuming that I have access to the mouse, or some other selection method (cycling through a container could also work)
the character has a collider that will mostly interact with the edge of the map, and the ground, then a boom, and the camera.
with the mouse you could do Line traces from the camera in the direction of the mouse (look at the Top Down Template for an implantation) though using the mouse would require casting at some point. then to issue commands (function calls) you store the Actor/Pawn/Character or array of such to then call the function for each of them. the hardest part is selecting the things you want to issue commands too.
If there is one character that always has a controller, then code can be placed in that character to select other actors and code to control them. But if you want to possess other characters then that (probably) won’t work. For example, if you are a wizard and want to turn into a wolf when you press a key. Maybe I didn’t quite understand you…
a Character can have a controller, but it doesn’t “NEED” a controller. An ACharacter is a APawn which is a AActor, and at the end of it all. these are just function delegates (a function call on a automatic trigger that can happen at some random point in time) that fire off functions, that call other functions.
so you could have an array of AControllableCharacters : ACharacter
then let them have exposed public functions (your choice on interface, or just public functions) then when you want to give them a command
for example right click could try to call MoveToAttack(APawn* Target)
, but if there is nothing to Attack then it would call MoveToLocation(FVector* TargetLocation)
where the thing you would bind would be APlayerControllingCharacter::RightClickAction()
which could be an APawn if you really want (just so the engine doesn’t throw issues with it wanting to have a controller.
the only limitation to calling functions on a class is the #include
which you can have a class derived from AActor with the knowledge of ACharacter (or something derived from it) you just might want to put that include in the .cpp file to prevent a circular logic error flag from your IDE.
I roughly understand what you mean, but what if you need to change the camera? You are probably talking about strategies where the controller controls the character, where the main role of the character is to control the camera and there is no need to switch the camera. Unfortunately, I do not really understand such games In my case, the character changes his appearance, abilities, controls, and the camera also changes. In my case Third person game. But your idea is very interesting, I need to think and experiment, I will definitely look at the top-down template. However, the idea of using a controller with an enhanced input is very useful, I would like to understand how to do it …
Unfortunately, I didn’t find an answer to my question. This is probably not a problem, but in some cases it is not convenient. If anyone finds an answer, I’d be very grateful.
What’s the actual problem?
Remove all input event handling from the Character and Pawn subclasses you’re using.
Add input event handling to the Player Controller subclass you’re using.
Set up the InputController on the PlayerController to be the enhanced input controller.
It should just … work.
What is your input component, if you stop in the debugger and investigate it?
SetupInputComponent()
is the call that’s supposed to create it, it’s not already made there, so, at a minimum, you need to call through to the inherited (APlayerController) SetupInputComponent() function first.