Can Someone explain this syntax?

I’m Just starting out with the Unreal 4 engine and programming in general. I have been trying to follow various tutorials trying to get a grasp on how to build a simple game using C++ but have come across a section of code that I cant understand. I believe this code comes from Epic’s “Introduction to UE4 Programming” video series on Youtube, However as this is my first attempt at creating something without a tutorial I may have found this elsewhere.

The Code is the following:

	static ConstructorHelpers::FObjectFinder<UBlueprint> PlayerPawnObject(TEXT("Blueprint'/Game/Blueprints/BP_playerPawn.BP_playerPawn'"));
	if (PlayerPawnObject.Object != NULL)
	{
		DefaultPawnClass = (UClass*)PlayerPawnObject.Object->GeneratedClass;
	}

Which is located in the constructor for my game mode class. This code sets a blueprint of my PlayerPawn class to be the default pawn class for my game mode. When The game is run the static mesh component associated with the blueprint is displayed as expected.

Even though this code is working, I am unable to understand the syntax that has been used. Could someone please try to explain in simple terms what is happening here. I will try to explain each line below as I currently understand them.

static ConstructorHelpers::FObjectFinder<UBlueprint> PlayerPawnObject(TEXT("Blueprint'/Game/Blueprints/BP_playerPawn.BP_playerPawn'"));

We are creating an object called PlayerPawnObject that holds information about the blueprint found in the given directory. I’m assuming that ConstructorHelpers::FObjectFinder somehow defines a data type but I don’t really understand what is going on here. In particular I don’t understand the angled brackets . I also don’t understand how the blueprints directory is able to be used as what seems like an argument when defining a new object.

     if (PlayerPawnObject.Object != NULL)
     {
         DefaultPawnClass = (UClass*)PlayerPawnObject.Object->GeneratedClass;
     }

The If statement is being used to avoid errors in the event that the PlayerPawnObject could not be created.

DefaultPawnClass is a parameter that is inherited from the GameMode class which defines the default pawn class for the game mode.

(UClass*) is being used to cast PlayerPawnObject.Object->GeneratedClass as a UClass pointer ?

PlayerPawnObject.Object does not make sense to me as I assumed that PlayerPawnObject was an object its self.
I am assuming GeneratedClass is a method within PlayerPawnObject that returns a reference to the objects class?
Why are empty parenthesis not required here? ie. PlayerPawnObject.Object->GeneratedClass() ?

Any assistance in helping me understand this code, or and documentation or reference material that may clear things up would be appreciated. Thanks :slight_smile:

You have a decent understanding of what’s going on, just some finer points on how I understand the system:

Angled brackets are generally used to indicate the type of object you’re looking for, so “< UBlueprint >” is simply telling the object finder you are trying to find a Blueprint type object.

Now, this object that the object finder finds, is a very generic entity, which allows a lot of flexibility in finding objects.
So if it finds the object you’re looking for, it populates the “Object” property of the ObjectFinder entity.
This would be analogous to defining a class, and having, say, a StaticMeshObject property on that class, and having some method called “FindMyStaticMeshObject”, which populates that property. The only difference is that there are some extreme meta-code and black magic going on in the Engine’s object finders.

So if this FObjectFinder.Object is not null, it simply means that it did indeed find an object of the type requested at the given asset path.

Now, Blueprints are set up via the Editor, BUT, in the back-end, it generates an actual class for each Blueprint instance (verification needed).
Blueprints can sort of be thought of as “A Class with specific defaults”. So it is similar to creating some base class manually, let’s say “MyWeapon”, which has a float property called “DamageAmount” with default value 20, and then creating a class derived from “MyWeapon” called “MyBigDamageWeapon”, where the “DamageAmount” is set to 100.
This “MyBigDamageWeapon” class, where the DamageAmount is explicitly set, is sort of the same idea as a Blueprint, except that you explicitly created that class. A Blueprint created by the system works slightly differently, but the main idea is that it generates an actual class for that Blueprint.

Now, when you’re finding a Blueprint object via the object finder, it contains a reference to that class which was created in the background in the “GeneratedClass” property.
In your case, this class is inherited from Character, and therefore the class reference can be used to set the DefaultPawnClass required by the GameMode.

I hope this helps a bit, but please feel free to ask if anything is unclear.

Thanks for your reply. I think I now understand what is going on in most of the code, however I’m still a bit confused with the line:

static ConstructorHelpers::FObjectFinder<UBlueprint> PlayerPawnObject(TEXT("Blueprint'/Game/Blueprints/BP_playerPawn.BP_playerPawn'"));

In case my terminology is wrong I am using the term ‘object’ here to refer to an instance of a class. So in this case I was assuming that PlayerPawnObject is an object of the class ObjectFinder. From your reply I gather that this ObjectFinder class contains an Object parameter which will contain a reference to the ‘thing’ (in this case a UBlueprint) that the FObjectFinder was told to look for. and since UBlueprints create classes in the background the class can be referenced using the GeneratedClass property of the PlayerPawnObject.Object. Is this a correct understanding? If it is what aspect of c++ programming do I need to research to better understand the use of the angled brackets (This syntax is still confusing for me). Also the parsing of an argument, in this case the blueprint directory, when defining a new FObjectFinder object is confusing me.

Finally, is there a better source of documentation that can help me understand things like FObjectFinder? I am struggling to find any help from:

FObjectFinder | Unreal Engine Documentation

Thanks. I think I understand. I have not yet come across templates and will have to look into this further, although from your reply it seems to make sense.

Also I can now see how the blueprint URL is simply the arguments of the FObjectFinder constructor.

Thank you both for your time and help.

It’s a rather interesting (ab)use of the typesystem to build a DSL for interacting with the UObject reflection system!

So, first, your question about angle brackets: that’s a template argument. C++ has a compile-time generics system called templates, which allow you to write out a bunch of code that works for a few different types – for example a vector that you define once, but can work with either doubles or floats internally. The compiler does this by “parameterizing” the templated type over the argument – returning to our simple example of a vector, you might define it something like this:

template <typename DataType> class Vector {
    DataType data[3];
};

and instantiated something like this:

Vector<float> myVector;

The compiler will produce something akin to the following:

class Vector_floatimpl {
    float data[3];
};

and

Vector_floatimpl myVector;

Applying this to the line that gave you trouble, you’re instantiating a static FObjectFinder – an Object Finder specialized just for finding Blueprints, that you’re only going to construct once at program start, and use each time you call this function.

Finally: the parens after the variable’s name. That’s nothing more than the arguments passed into the arity 1 (takes one argument) constructor for FObjectFinder, specifically the one that requires an FText as the argument (the TEXT(…) macro emits those).

Now, there’s one more piece to all of this that’s less C++ idiom and more Unreal. C++ has a simple reflection system called RTTI (runtime type identification), which provides a tiny sliver of what the UObject system gets you – when you write those UCLASS/UFUNCTION/… macros, you’re telling UHT to generate some headers with a whole slew of code that allows you to query properties of your types at runtime. I’d suggest reading more about that over here.

Great stuff! You’ve clarified the technical details of the template system for me too. Thanks!