Why can’t I bind to an object other than this? I know I could bind to wrapper functions that call the actual function. But there must be a direct way or am I wrong?
Probably because SetupInputComponent() on PlayerController is called before the character is created, so GetCharacter() returns null at this point and you are binding to nothing.
The character has its own input component. You can override SetupInputComponent in character class to bind actions there.
If you really want to do everything in PlayerController, you’ll have to rebind actions to the character every time you change character. Override function OnPossess in playercontroller and do the binding there like you did with GetCharacter()… I wouldn’t recommend this approach though…
Alternatively, you can bind actions to PlayerController functions that simply forward to the current character in real time. Something like this :
I know there is ACharacter::SetupPlayerInputComponent and it’s also used in the project templates. However, don’t you thinks it’s kind of violating the single responsibility principle? Isn’t this exactly the PlayerController 's responsibility?
I think even better would be if the PlayerController holds a reference to an Interface that is implemented by a Character or a CharacterInputComponent and BindAction on that, but this needs even more wrappers.