Blueprints can develop a hard reference dependancy chain, but C++ derived classes do not?

If your variable is always going to point to an object that exists at runtime or null it actually doesn’t have to be a soft reference, you can make it a hard reference as the difference of hard/soft BP references mostly make a difference when loading the parent asset.

But it’s good to get the basics cleared up, so let’s take a look at what makes a hard reference!

When you have an Object Reference variable of a certain Type, the variable’s Type will be a hard reference:

image
↑ Variable ChildActor’s Type is BP_TestChildActor. This means that it can hold any object that is or extends that type. But a variable’s Type itself will always get hard referenced so it also creates a hard reference to that class, even though ChildActor is set to null.

(When using a variable of the type Actor Object Reference you can only set the default as level actors in the Class Defaults since it only allows you to point to runtime or level actors.)

To remove that hard reference to the type you’ll need to use some Type that doesn’t count as a hard reference. For those you can use C++ classes or Interfaces.

image
↑ In this example the variable has been made to be an Actor, a C++ class. Now there’s no hard references when loading the parent actor.

In the example above we do lose all type information though, since we’re casting to such a basic class as Actor. A good option would be to have some more specialized base class for the variable to be able to call functions on it, by creating a new base C++ class with some empty functions and then override the functions in the child blueprints. Or, easier, to make a BP interface.
If you were to change the type to a Soft Object Reference it wouldn’t change much, soft references are mostly for storing references to assets that you want to reference but not load directly, or to actors in levels that might not be loaded/exist yet.

Then we have a variable with a Class Reference Type of variable. Just using a normal hard reference:

image
↑ In this case the Type of the variable is creating a hard reference to BP_TestChildActor, and the Value of the variable is also creating a hard reference to the class default that has been set, in this case a subclass of the BP_TestChildActor called BP_ExtendingChildActor.

This gives us two hard references. All child classes extending BP_TestChildActor of course also hard reference their parent class so that additional reference from the type is not a big deal.

Now lets say we make the variable be of the type Soft Class Reference:

image
↑ In this case, even though the variable is a soft class reference, the Type of the variable is creating a hard reference to BP_TestChildActor. However, the Value of the variable does not create a hard reference.

In the above example we can mitigate the hard reference again by using a C++ base class or an interface. Meaning that there will be no hard references to assets at all.

I hope this makes things a bit clearer. Like I said before, I think that a Soft Reference having its Type actually make a hard reference is not great and something that should be fixed in Unreal Engine, but like I mentioned there are ways around that until if and when we do fix that.

I’ve made a couple of resources that go a lot over the topic of references that I heavily recommend you check out to get fully versed in the topic:

4 Likes