Get Actor Component Reference in C++ Class

In like the BeginPlay of ComponentB you can do

A = GetOwner()->FindComponentByClass<ComponentA>();
2 Likes

I have made two ActorComponent Class in Unreal Engine and attached them to my Player Actor. I wish to include a reference for ComponentA in ComponentB. So that I may access its functions and fields. What is the pattern to do this in Unreal using C++? I am new to Unreal Engine coming from Unity and am trying to understand the pattern for referencing different actorComponent classes.

In Unity C# I could just get a component attached to the same parent using something like this:

ComponentA componentA = GetComponent<ComponentA> ();

Where ComponentA is the other component script I want a reference to in ComponentB. Both are attached to the same parent. I assume there is something similar in Unreal Engine but I can’t seem to find it.

Broadly speaking I have many component classes that will live under my Player Actor. Classes like PlayerPhysics, ActionController, InputController, IndividualAction classes, Aniimation classes and so on. I’m trying to find an effective way to access the different classes under my Player Actor.

I saw this a few places but kept disregarding it because it was said to be expensive. Is that true or is it fine for just running during BeginPlay? Cause that’s really what I want to do. In Unity I used to Start() method which has a similar function to BeginPlay.

It’s not too expensive, not even close. Some code does such lookups at runtime, so doing it within a function that’s called once for an actor is even less of a concern.

I suggest doing it in InitializeComponent rather than BeginPlay, but either should work, though I think InitializeComponent might be C++ only.

For examples
UBrainComponent::InitializeComponent()
UBlackboardComponent::InitializeComponent()

That said, if you find yourself doing such component lookups in a tick function, you should really consider caching it if possible.

Hi, what if there are multiple components of the same class added to the pawn? What would be the ideal way of passing a reference to the component I want? I am not so worried about performance (since is just once in the beginning), but I wonder why is it not possible to select the right component instance from the dropdown menu if I create a variable of the right type?

For instance, if you create an actor variable on the pawn and expose it, you can use the dropdown list on the pawn instance to select which actor instance you want from the scene.

BUMP on the last comment above mine. This is laughably easy to do in Unity by just dragging components onto the reference slot in the inspector (aka details panel), but seems difficult to impossible in Unreal.

1 Like

So this is an imperfect solution to the question about adding a specific component, but it will get the job done and maybe someone can add the last little bit.

In the C++ code of your component add:

		UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyCategory")
		USceneComponent* MyComponent;

This will add a Scene Component pointer variable to your component which you will be able to edit in Blueprints. Here’s the imperfect part. When you click on the variable to change it, it gives you a list of scene component classes rather than allowing you to drag or point to a scene component on the actor. To solve this go into the actor’s construction script and drag in your original component. Drag off the pin and search for “Set {name of variable}”. Once you have this node you can drag in your target component to set that as the value of the variable.

Like I said, not perfect, but it does get the job done. I’m sure there is a setting in the macro or something that would allow you to set the variable directly, but this gets the job done for my purposes, so I’m not going to worry about digging around for it at the moment.

1 Like

Ahh thanks so much for this. I was tripped up because the “MyCategory” didn’t seem to appear in the blueprint editor (under “Class Defaults”). But using the construction script to set it works perfectly.