How to manage MyCharacter to handle 30 differents characters?

Hi,
Currently I have a simple MyCharacter class doing several basic actions like sprint, double jump, fire different projectiles, etc. In my project the player will be able to choose his avatar from a list with 30 differents avatars. Each avatar will have special mesh, skeletal mesh, skills, stats, weapons, etc.

How I manage that ?

Option 1 : MyCharacter become the parent class and I create 30 children classes inherit the parent basics fonctions, each with dedicated values, skills, meshes, etc (most values handle via BP - 30 BP required).

Option 2 : MyCharacter become the parent class and I create an unique child classe inherit the parent basics fonctions. the child class has several arrays with all stats, skills, meshes, etc, and I use parameters to the constructor to select the right value in each array (is that possible ?).

Option 3 : MyCharacter has several arrays with all stats, skills, meshes, etc, and I use parameters to the constructor to select the right value in each array.

Option 4 : Other solution ?

Waiting your reply.

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

All of those ways would be valid. I think because the different characters have different skills you might want to look at it from the PlayerController instead of from the Character, so go up a level.

You probably want to break up the different types of characters into groups, such as by class type or some other means that makes sense for your game. That way, instead of having 30 child characters of 1 parent character, you will have 4 or 5 child characters from the parent, then under each of those will be 4 or 5 sub-children that are similar to their parent but change in some way.

You can either figure out a way to make the controls generic in the Parent PlayerController, such as ActionX, ActionY etc. and then implement them differently in each character, so the PlayerController calls ActionX any time the left mouse is clicked, then it calls ActionX on the Character, but each implementation of the Character will do it’s own thing inside the function.

You could also instead break up the PlayerController in a similar way, sub classing it and having the main PlayerController pass it’s commands down to the child controllers.

There are either a gem or tutorial on how to do something like that in UDK, setting up a framework to have component Controllers. But it would be a bit different in UE4 though a similar idea. Taking the time to setup a good framework ahead of time will save you a lot of head ache later trying to just have 30 separate characters extending 1 parent character, but, it is valid to do that if you don’t want to deal with the complexity of setting up a sub classing character and Controller setup.

Great ! Thanks for your reply and code.