How to manage MyCharacter to handle 30 differents characters?

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! =)