If all you are manipulating in the child classes of MyCharacter
are attributes like “Skills”, “Mesh”, “Weapons” then you could do a number of things. First, something that I think you should consider to help organize your data is using structs, or USTRUCT()
.
You could create a structure for each genre of attribute for your MyCharacter
class and it could really help you keep things organized.
An example is my weapon class, I need to maintain many different values for each weapon. Here is what I did:
In the header file, I created the struct to hold all the data…
USTRUCT()
struct FMWeaponData{
GENERATED_USTRUCT_BODY()
UPROPERTY(EditDefaultsOnly, Category = Type)
TEnumAsByte<EWeaponType::Type> WeaponType;
// total uses (Combos/ammo)
UPROPERTY(EditDefaultsOnly, Category = Usage)
float StaminaCost;
// total uses (Combos/ammo)
UPROPERTY(EditDefaultsOnly, Category = Usage)
float StaminaCostCharging;
// time between uses
UPROPERTY(EditDefaultsOnly, Category = Usage)
float timeBetweenUses;
// determines if this weapon has the ability to charge
UPROPERTY(EditDefaultsOnly, Category = Charging)
bool bIsChargable;
// determines if this weapon has the ability to charge
UPROPERTY(EditDefaultsOnly, Category = Charging)
float maxChargeValue;
UPROPERTY(EditDefaultsOnly, Category = Damage)
float DamageAmount;
UPROPERTY(EditDefaultsOnly, Category = Damage)
TSubclassOf<UDamageType> DamageType;
// defaults
FMWeaponData(){
WeaponType = EWeaponType::Primary;
StaminaCost = 25.0f;
StaminaCostCharging = 5.0f;
timeBetweenUses = 1.0f;
bIsChargable = false;
maxChargeValue = 3.0f;
DamageAmount = 20.0f;
DamageType = UDamageType::StaticClass();
}
};
Then I create a variable that has the ability to be modified in Blueprint, if I want.
// weapon data
UPROPERTY(EditDefaultsOnly, Category = _Config)
FMWeaponData WeaponConfig;
Now that some organizational tips are out of the way lets talk about some possibilities for you.
Option 1 : This is not a bad idea and would work fine. It would be a lot of Blueprints to have laying around though, as you mentioned.
Options 2 : This is not a good implementation. If all of your characters share the same attributes there is absolutely no reason to re-code all this stuff in every child class… this is what inheritance is used for.
Option 3 : You could do this as well. I would use the structs thought to keep it organized. This would also require you to have many Blueprints or child classes of MyCharacter
.
My Suggestion : I would create an enum of CharacterClassType
and just have 30 types.
Example:
UENUM()
namespace ECharacterClassType{
enum Type{
Knight,
Ninja,
... 28MoreTypes,
};
}
Then in your header file, in one of your configuration structs:
UPROPERTY(EditDefaultsOnly, Category = Type)
TEnumAsByte<ECharacterClassType::Type> ClassType;
What you would have to do then is create an initialization function for each class type in the MyCharacter
class that initializes all the attribute values for that class.
You would have one massive switch
statement that would take the ClassType
variable value that you set and then it would call the appropriate initialization function.
switch(ClassConfiStruct.ClassType){
case Ninja:
InitNinja();
break;
case ... 28More:
InitWhatever();
break;
...
}
So you could now simply have one Blueprint for MyCharacter
and spawn that in the game. Then depending on what class you want, set that ClassType
variable to the desired class, then call a function that contains the switch
statement that will initialized it for you.
This might not be exactly what you are looking for but you can use this info to make something that fits your implementation. This method seems to be very simple and also very dynamic. I think it has the least amount of coding as well.
Hopefully this helps! =)