Interfaces In C++
Introduction An interface is an object-oriented programming concept. It is an elegant version of multiple inheritance that helps to preserve a linear UObject hierarchy in UE4. For example, a charac...
Introduction
An interface is an object-oriented programming concept. It is an elegant version of multiple inheritance that helps to preserve a linear UObject hierarchy in UE4. For example, a character in a game may need to be able to interact with non-player characters (NPCs) as well as certain static objects. One could create a parent class that implements interaction functions and then make both the NPCs and static objects inherit from it; however, it may obfuscate the overall class hierarchy of the project. It would also be a complicated process in a huge project with many different NPC and object classes. To sum up, when unrelated classes need to implement the same functions, using an interface will make the code more modular and thus easier to read, debug, and maintain.
Interfaces can help you cut down on casting classes saving resources in the process, you can easily implement the same function across classes, but interfaces allow you to call the function without knowing the class of the object by calling through the implemented interface instead.
Creating Interfaces in C++
You may create your interface from scratch. After all, at its core, it is simply a class other classes inherit from. However, in most cases it is best to benefit from internal UE4 code so you may want to inherit from the UInterface class when creating a custom interface. The easiest way to do it is to right-click anywhere in the Content Browser of the UE4 Editor, select New C++ Class, and then choose Unreal Interface at the bottom of the list of parent classes. If you follow this method, note that two classes will be created: one that starts with a letter U and one that starts with a letter I. Assuming the custom interface is called YourInterface, they will appear like so:
UINTERFACE(MinimalAPI)
class UYourInterface : public UInterface
class YOURPROJECT_API IYourInterface
This may seem confusing. As the comment at the top of the header file will tell you, the UYourInterface class is intended to be left empty. It is there only for the UE4 reflection system. On the other hand, IYourInterface is the actual interface class and all your interface functions should go inside it.
To apply the newly created interface to an object of your choice, open its header file, include the header file of your interface, and add the dependency to the object class declaration like so:
class YOURPROJECT_API AInterfaceActor : public AActor, public IYourInterface
The above code snippet shows an Actor class as an example, but you can apply an interface to any UObject.
Due to the nature of interfaces, chances are a great many of the interface functions you write will be virtual. When adding an interface to an object, you must ensure all appropriate functions are overridden by the object. In case you need to call the parent implementation of some interface function in your object, remember to use
IYourInterface::
instead of
Super::
.
Using Interfaces in C++
To use an interface, one must first determine if the given object implements it. Since an object that implements an interface inherits from that interface, you may think that casting the object to the interface class is the most obvious way to find out. This is indeed one of the ways of doing it, as shown in the code snipped below, where the cast will succeed (return non-null) if YourObject does implement YourInterface.
Cast(YourObject);
Casting fails on some objects even if they implement the interface, like level BP actor with a C++ interface. So avoid using casting if you can.
Use "Implements<>" to check and "IMyInterface::Execute_TestFunction(Actor)" to execute instead.
While the above method works, there are two other ways that may be much more convenient. The first one uses the UClass of your object to determine whether the object implements an interface, and the second one uses the object itself. The code snippets below show an example of each. Note that here you should use the U-prefixed version of your interface class.
bool bUsesInterface = ClassOfYourObject->ImplementsInterface(UYourInterface::StaticClass());
bool bUsesInterface = YourObject->Implements<UYourInterface>();
Once you have determined that the object does implement the interface, you can call the interface functions the same way you would call any other function of the object.
C++ Interfaces in Blueprints
UInterfaces are Blueprint implementable by default. This means that attempting to use the
BlueprintCallable
function specifier will result in a conflict. If you wish to use this specifier on your interface functions, you have to give up the possibility of implementing the interface in Blueprints using the following meta specifier for the interface:
UINTERFACE(MinimalAPI, meta = (CannotImplementInterfaceInBlueprint))
class UYourInterface : public UInterface
On the other hand, if you would like to be able to implement the interface in Blueprints and call some C++ functionality from there, you must use the
BlueprintNativeEvent
specifier. Also note that
BlueprintImplementableEvent
specifier also works with blueprintable UInterfaces. Refer to UE4 documentation or this blog post by Tom Looman to learn more about the function specifiers mentioned in this section.
Finally, you can always add the blueprintable meta specifier to your C++ interface class in case you prefer it to be more visible that your interface is in fact Blueprint implementable.
UINTERFACE(MinimalAPI, meta = (Blueprintable))
class UYourInterface : public UInterface