TMap values working in C++ but not in blueprints

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:

In BeginPlay in my AbilityManager.cpp class, I am adding a dodge ability and attack ability to my TMap:

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.
blueprintTMap

Does anybody have an idea why it works in c++ but not in blueprints?

You need a unique key for the map for it to work

Example of it implemented. Just change the api_
abilityTest.zip (1.8 KB)

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.

Wouldn’t it be easier to just use a TArray, casting the EAblityType to an int to use as an index?

Well my files work. I uploaded the headers and cpp for the two needed classes.

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.

AddUnique function exists to avoid this situation

Even if you use AddUnique, it’s still O(N) time complexity, whereas using a map has the advantage of O(1) lookup, search, add, and removal.

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.