Download

Attaching custom UObject to character

So I created my own class (called emotions) from an empty C++ constructor that has an FString and float value along with basic set/get functions. I then made a new UObject class where I have a TMap variable containing FStrings as keys and emotions as values. How do I attach this UObject to an actor/pawn?

I ultimately want to have these emotion’s values changing throughout the game based on player input and helping decide what event my character/AI does. I’m still new to Unreal so any suggestions are welcome as well. Thanks in advance!

I would make it into a component, by letting it inherit from UActorComponent.
Then I would add it like you normally add a component/subobject:

YourActor.h:



private:
   UYourComponentClass* Component;

public:
   AYourActorClass(const FObjectInitializer &ObjectInitializer);

   /* Getter for private component */
   UFUNCTION(BlueprintCallable)
   UYourComponentClass* GetComponent() const;


YourActor.cpp:



AYourActorClass::AYourActorClass(const FObjectInitializer &ObjectInitializer)
   : Super(ObjectInitializer) {
       Component = ObjectInitializer.CreateDefaultSubobject<UYoutComponentClass>(this, TEXT("Name of component"));

}

UYourComponentClass* AYourActorClass::GetComponent() const {
   return Component;

}


The above should work, with the object spawning in editor as well as in PIE/build. Just make sure to let your UObject inherit from UActorComponent…

Don’t use FString as map keys, use FName. Hashing a FString is slower than FName. Hell, if your number of keys is low, a TArray of structs with a FName key would probably be faster than a map due to the overhead involved in hashing. Also, TMap cannot be used as a property but TArray can.

Not everything needs to be a UObject, either. From your description, it very much sounds like you could get away with just storing a small struct containing your data.

-Camille

When I add public UActorComponent after public UObject I get this error

Emotions.h(14): error : In Emotions: Implements: Class ActorComponent is not an interface; Can only inherit from non-UObjects or UInterface derived interfaces

Thanks for the heads up Camille :slight_smile:

Scratch that, made a UActorComponent class called EmotionsComponent that contains a TMapBase with FName as keys and Emotions as type. Upon construction of this component, I add the 5 emotions I’m using to the TMapBase and have some basic get/set/change functions that all seem to compile alright.

The component also shows up in blueprints as well as the functions. How can I test this component to make sure everything is ok in it? I just want to be able to see if all the values are currently set when I do something like getEmotion().

(sorry for double post)

For UProperties (which TMap can’t be), you can view the values at runtime by using the console command displayall. For instance:

displayall EmotionsComponent EmotionMap

When debugging/validating, I sometimes create UStructs or other debug properties just for use with displayall. You could have your getters/setters maintain a temp array just for this purpose.