So I have an ActorComponent class called “AbilityManager”, which I’m using to keep track of abilities the player currently has. To store all abilities, I’m using a TMap with an Enum as the key, and the ability object as the value.
Here’s my TMap declaration in AbilityManager.h:
When I use visual studio debugger, it shows that I have two values in my TMap (my attack and dodge abilities are both there). However, for some reason in blueprints, only my dodge ability shows up in the TMap, which is causing my blueprints to fail.
Does anybody have an idea why it works in c++ but not in blueprints?
They are unique, the dodge key is EAbilityType::Dodge, and the attack key is EAbilityType::Attack. The console print lines at the beginning of my BeginPlay function also show (when the application is running) that the uint8 translation of EAbilityType::Dodge is 1, and the uint8 translation of EAbilityType::Attack is 3.
I could, but it’s more efficient to use a map since they can’t have duplicate keys, and I don’t want the player to ever have more than one instance of a given ability. If I used a TArray I’d have to check the whole array for duplicates each time I add a new ability.
I also prefer maps to arrays when it’s possible, I’ve just corrected a wrong affirmation.
Going back to your problem, I would try to create another blueprint based on your C++ class, it’s a known bug that Blueprint are not refreshing, sometimes, after changes in C++
Maybe I’m missing something, but I was thinking it was much more efficient - rather than having to do any type of lookup/search it’s just “index*(sizeof ptr)”
UENUM(BlueprintType)
enum class EAbilityType : uint8 {
Ability1,
Ability2,
Ability3,
Ability4,
MaxAbilities
};
class UAbilityBase : public UObject {
public:
};
class UAbility1 : UAbilityBase {
public:
};
TArray<UAbilityBase*> myArray;
int32 EnumCastToInt32=(int32)EAbilityType::MaxAbilities; // =4
myArray.SetNum(((int32)EAbilityType::MaxAbilities)+1);
EAbilityType myAbilityType=EAbilityType::Ability1;
myArray[(int32)myAbilityType]=NewObject<UAbility1>(this,"Ability1"); // Replace with your own construction
UAbilityBase* abilityImWanting=myArray[(int32)EAbilityType::Ability1];
I figured out the issue kind of. Just in case anybody else stumbles upon this, I was creating my abilities in the constructor using CreateDefaultSubObject(). I ended up replacing this with NewObject() in BeginPlay() instead, which seems to have fixed the problem. I’m not exactly sure why the former method was acting strange but I suspect it has something to do with C++ constructors being ran before blueprints.