How to get a Pointer (in C++) to a Blueprint Actor in the Scene.

Hello,
I have a Blueprint called “BP_SplineTrack” and there is an Instance/Actor of it in my Scene. I also have a UCLASS in c++ and want it to have a private Pointer to that Actor, so that I can call a Function of it later on.

How do I do that?

Currently I have something of that sort:

UClass* SplineTrackBlueprintClass = FindObject<UClass>(ANY_PACKAGE, TEXT("BP_TrackSpline"));
m_SplineActor = UGameplayStatics.GetActorOfClass(GetWorld(), SplineTrackBlueprintClass);

But m_SplineActor is a AActor pointer and no BP_SplineTrack pointer, so the compiler throws in error when I try to call the BlueprintFunction later (using the arrow operator ->)

Thanks for all the help!

P.S. Please have in mind, that I’m fairly new to Unreal Engine

You cannot call pure blueprint functions from C++.

What you need to do is create a C++ class derived from AActor and set it as the parent class in your BP_TrackSpline. Then you can use UGameplayStatics::GetActorOfClass() and find the actor of the C++ class you’ve created.

In turn, in that C++ class you can have a public function marked with UFUNCTION(BlueprintImplementableEvent) that you can call from C++ and make it perform the actual function in the blueprint.

:heart: Welcome to the UE Forums @ullriche !!! :heart:

For this type of use case, I would recommend that you

  1. Create a BP of the GameState class, and have your own C++ version of the GameState that you then make a BP of.

  2. Add a variable of same type as the C++ version of your custom actor (which you mentioned you then made a BP of) to the C++ custom Game State that you make.

  3. In BeginPlay of your BP of your special actor, have the actor register herself with your GameState using GetGameState (Cast) Your custom GameState BP. This part is in blueprints. You could do this in C++, but after working on many projects, I recommend you use C++ only for things that have to RUN FAST or are complicated math logics, because your game project will be the fastest to iterate on, and the easiest for other people to help you with later, if you keep as much core design flow in BP as possible.

  4. In C++, you can now retrieve the C++ version of your special actor, again using


UWorld* World = GetWorld();

if(!World)
{ 
   //This can and WILL happen! so make sure to check your C++ ptrs! ♥ Rama
   return;
}

AYourCPPGameState* AwesomeGameState = Cast<AYourCPPGameState>(World->GetGameState());

//or AYourCPPGameState* AwesomeGameState = World->GetGameState<AYourCPPGameState>();

//Will be nullptr if you don't set Your GameState to be used in Project Settings -> Your Game Mode
if(!AwesomeGameState)
{
    return;
}

AAwesomeCPPActor* SplineActor = AwesomeGameState->YourVariableThatWasSetInBeginPlay;

if(!SplineActor)
{
    //variable was not set yet, make sure this C++ code runs AFTER Begin Play!
   return;
}

SplineActor->DoThingsWithYourSplineInstanceYay();

Why This Coding Paradigm?

I recommend this workflow because you are setting things in BeginPlay, using EXACT variable references, not dynamic look ups like FindObject or ActorIterator.

Dynamic look ups are Slow, you know Exactly which actor you want, so set the variable yourself to be supremely efficient for runtime game experience!

If you need to store more than 1 of the same type of actor to be referenced later, you can use an array in GameState and give your actor a special name, or use the ActorTags that come with UE::AActor.

The point is, the GameState is designed both in theory and in implementation to store information like this, basically, the Runtime State of the World.

So GameState = WorldState, and is supposed to store references to things that exist PER LEVEL in your world.

The GameState is also replicated to clients, and if ever server and client had to agree on something, like which actor a variable is currently pointing to in the world, this is also the precise class (GameState) where this type of replicated World Information should be stored!

Finally, you can get access to your GameState ANYWHERE in C++ or BP using GetWorld()->GetGameState().

So this is how you can easily access World Information of your own choosing, from anywhere!

:zap: :sparkling_heart: :zap: Lastly, other programmers you might ever work with will expect this sort of usage of GameState, and so your game will be very UE-Programmer Friendly when others join your Team! (Or You join Their UE Team!)

:heart:

Rama

1 Like

In this situation it’s best to port BP_SplineTrack to c++ and cast to the c++ class.

UGameplayStatics.GetActorOfClass(GetWorld(), CustomSplineTrack::StaticClass());