I have a multiplayer C++ project. I have 1 main ACharacter C++ class.
I have one main BP based on that class that gets assigned a skeletal mesh among other things.
I have two other Character BPs, that inherit from the main Character BP. The only difference in this two child BPs is the skeletal mesh. Other than that, all functionality inherits from the main bp and main c++ class. Also, there is 1 single AnimBP that all three share. When I load them up individually by specifying the default pawn in the GameMode BP, they all work great. All animations work, all functionality work etc…
I’m kind of stuck on something here though and looking for some guidance, on how to best implement this.
I need to be able to have two teams. How to divvy up players between teams is not the hard part, the part that I am struggling with is how to assign them different Character Blueprints. I want to have one character bp for one team and another character bp for the other team.
From inside the C++ code, say the GameMode class that I’ve implemented, can I load a character blueprint of my choosing and assign it to a player controller?
One thing that I got to wondering about is, that I have 1 C++ class that is my main character player class, that my main character BP inherits from. Then I inherit two other BPs from the main BP. Is this ok? Or should I be creating child classes from my single C++ character class? One for each character that I want to have? And then derive my character BPs from those?
In your blueprint GameMode subclass (make one if you don’t have any), override function GetDefaultPawnClassForController. Get player team from the controller and return the appropriate character class to use.
If you want to stick to C++ (mostly), add two new variables and override the function :
Thanks for your help.
I do have a child GameMode C++ class. I also have a BP for my child GameMode class.
If I am understanding hat your saying correctly, you’re saying add the following code to my child GameMode class? Then in the blueprint for it, assign the two ACharacter values.
Also, who calls this function? Is it an instance of the APlayerController class? Is there anything I need to do in that class?
BTW, I was thrown for a loop for a bit on how to override that function. I didn’t add the _implementation to the end of the function name and was getting issues with not being able to override that function.
I’d really like to understand this better because this is the first time I’ve seen overriding something like this… My RPC call stuff is still a bit foggy still and hoping to learn something here.
When looking in GameModeBase.h, I see the declaration for this method.
/** Returns default pawn class for given controller */
UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category=Classes)
UClass* GetDefaultPawnClassForController(AController* InController);
It doesn’t have any type of RPC indication in the function name or in the UFUNCTION() specifier. Nor is the function virtual.
So, is this an RPC function? If not, why does it have _Implementation in the CPP file when defining the function body?
My understanding is that RPC calls always need to have _Implementation in the CPP file when defining the RPC function which this does. But again, there is nothing indicating this is a RPC
It is a function from AGameModeBase, called by the engine to resolve what pawn to use whenever a pawn needs to be spawned for a given controller. You don’t need to call it, the engine does by default (as long as you use the framework properly), all you have to do is override it.
It is not an RPC, simply an almost-regular function, except that is has the BlueprintNativeEvent specifier which means the function can be implemented/overriden both in C++ and Blueprint subclasses. The entry point GetDefaultPawnClassForController has an auto-generated implementation that is basically a dispatcher to either the blueprint override, or the native override version with _Implementation postfix. The original declaration for virtual UClass* GetDefaultPawnClassForController_Implementation(AController* InController); in ABaseGameMode is automatically generated as well.