Download

Proper method for getting correct references to classes and/or components within your project?

I was following along with the course in the UE4 Online Learning center called Converting Blueprint to C++, and I noticed that while the instructor did a lot of great work that was informative, he would CONSISTENTLY skip over the “hard” stuff and just leave it implemented in Blueprint. This seems to be an extremely common aspect to many UE4 “C++ tutorials” in my experience, and it really infuriates me. This is usually anything with referencing functions in other classes or sometimes converting functions in general that do something more than just simple math or a getter/setter.

The guy even showed how to create a dynamic multicast delegate and bind it to an event in C++, yet he couldn’t show how to get the proper reference to a component and left it in blueprint.

That’s what drove me to make this post.

UE4Editor_KRjb2ZiJTa.png
In the first person character in this tutorial, it has a Grabber component which lets it pick up physics bodies that are in front of the camera via GrabComponentAtLocationWithRotation(). You can see the hierarchy in the screenshot.

My question is this:
How can I get a proper reference to that Grabber component in order to call Grabber->Grab(); from within the FirstPersonCharacter.cpp code? Basically I want the characters input action to call the Grab() in Grabber.cpp.

I am familiar with casting, and in previous projects I’ve done something like:



AMainCharacter* mainChar = Cast<AMainCharacter>(OtherActor);
if (mainChar)
{
    mainChar->SomeFunction();
}


But I searched through that code and noticed that every time it relied on either casting from the OtherActor in the case of an overlapped component, or a damage causer, or if it wasn’t that it was something like:



enemyPawn = TryGetPawnOwner();
if (enemyPawn)
{
    // casts enemyPawn as a enemyClass type so there's a way to access variables in AEnemy_Base
    enemyClass = Cast<AEnemy_Base>(enemyPawn);
}


Where it can access the class through casting an owner.

What if I just want to call a function in a component class that is a part of my character? Or what about getting a totally unrelated class in general? Is there a way to access all the different classes in a project via getting the game mode or game state, something like that? I’ve tried searching the forums and the web, but haven’t found the specific answer I need. I was hoping someone here can either point me to where I can properly gain this knowledge so I don’t keep coming up against this and getting stuck in the future.

Any advice would be greatly appreciated.

I’m a rooky and surely don’t know every possible way to find objects.
But in your case i would say the simplest design is to create the grabber in c++, you’ll have a reference in your character.cpp and blueprint also.
You could also use AAcor::GetComponentByClass(AYourGrabberClass::StaticClass), which in my view is a lot less convenient than the above.

Sorry, I know I posted a pretty large wall of text, but I was trying to explain that I already did create the Grabber component in C++. The problem is that the C++ character and grabber have no way to see each other. They have no context of each other. All the context resides in the BP object which is where I got the hierarchy screenshot.

I can create a pointer to the grabber, but I have no way to cast it. That’s why I mentioned that most of the casting I’ve seen done previously comes from a source, like a hitActor after a line trace, or an overlappedActor, or from getting an owner of something.

There MUST be a way to get access to any class without a mandatory overlap/hit/etc.

This is what I think I really need to know… what is the “general” source when you need a pointer to a class if you can’t overlap it, can’t hit it with a trace, and can’t get it from its owner? If Blueprints can do it, there is a way.

In a BP, you literally drag and drop the component from the hierarchy tree and you get a correct reference to it right there, with access to all of its contents, such as in this screenshot. This is what I need in C++.

By “create the grabber in c++” I meant create the class and add it as a component in c++:

YourCharacter.h



UPROPERTY(VisibleAnywhere, EditDefaultOnly)
class UGrabberComponent* MyGrabber;


Inside constructor, or OnPossess, or BeginPlay… YourCharacter.cpp



MyGrabber = CreateDefaultSubObject<UGrabberComponent>(TEXT("MyGrabber"));