I’ve been working with Unreal for 3-4 months now and feel like I’m starting to wrap my head around it pretty well, or at least the core parts of it — there are large parts of the engine I haven’t even tried to use yet.
But, there is one high-level thing I’m having trouble understanding. I understand the difference between Pawns/Characters and Controllers, and it’s a great design. What I don’t understand is why input handling code is in [FONT=Courier New]APawn and its descendents.
The Unreal 4 Architecture documentation describes the Player Character this way:
A PlayerController is the interface between the Pawn and the human player controlling it. The PlayerController essentially represents the human player’s will.
Based on reading this, and knowing that the Pawn/Character is supposed to be “dumb”, I would have assumed that player input would be handled by the [FONT=Courier New]APlayerCharacter subclass. The input is how the player expresses their “will” that they want the character to enact. But, [FONT=Courier New]APawn has a method specifically for setting up input and all the sample code and tutorials use that class. It is clearly the Unreal Way of doing things to handle input in the pawn or character.
It’s not really important in the grand scheme of things, and I plan to do it the Unreal Way, but I feel like I must be misunderstanding the exact nature of these two classes and their relationship with each other. Based on my understanding, input handling seems like a natural fit for the player character class not the pawn or character subclass.
I have the exact same question, will be following this thread.
It seems almost against the best programming practices from a UI perspective for example. Where the UI shouldn’t know anything about the code underneath it that drives it. This loose coupling makes it easy to replace components at a later date easily.
I thought the same thing, so I did it differently.
If you use interfaces that the pawn implements, it’ll react to input messages rather than poll input itself.
As soon as you create a Blueprint Interface, any functions you add to it are simple declarations (the definition/body of each function is fleshed out in any pawn/character than implements them). Additionally, anything can call those functions, which will dispatch an event.
N.B. You need to add a ‘dummy’ output to the interface’s functions, otherwise they won’t show up in blueprints that implement that interface (I just return an empty int).
Been wondering this as well, would love to hear the reasoning behind it. Whether there’s a good reason, or it just hasn’t been cleaned up yet, or whatever, I don’t care, just want to know the reason so I can make a more informed decision on how to properly handle this.
I get your reasoning there, but I’d rather do it the way it intutively sounds like we should with this segregation of responsibility. That way the same pawn can be player controlled or AI controlled without much difficulty, just swap out the controller. You could even do it Left 4 Dead style where the AI takes over as soon as the player disconnects/goes afk and then the player takes over as soon as they connect and click to take control.
Again, unless there’s a good reason why we shouldn’t do it that way.
It also makes it easy to swap around at runtime. Want an FPS where you can switch between different characters quickly? (a Rainbow 6 style game would be a good fit for this) Want a GTA style game where the player can control a human pawn, which then gets in a car, or a motorcycle, or helicopter, or plane, or boat, all of which mostly control similarly but react to the same inputs in different ways? (Oh, and don’t forget the player can also switch from the driver’s seat to one of several passenger seats, in which case there will be yet another way to respond to most inputs.)
That explains the problems I’ve been having with Interfaces! Thanks for the tip! Any idea why that is? I had just assumed I was doing something wrong and couldn’t figure out what it was, so I left the blueprint cleanup for later.
Happy to help I’ve seen this come up a few times, so I’m considering writing a tutorial.
What would be preferred - using blueprint interfaces to link input events to C++/BP code, or straight C++ interfaces? The former definitely has more flexibility, which is exactly what you’re after with decoupling anyway
I’d say Blueprint interfaces, personally I have enough experience with C-family interfaces. And if it’s more flexible to use Blueprints anyway, then might as well. The way Unreal is structured you’re unlikely to want to avoid Blueprints, but sometimes you want to avoid C++. (iOS deployment from Windows) Examples of working with Blueprint interfaces from C++ would be nice though.