This post is an attempt to ask and answer some questions about using
interfaces in c++ and blueprint that collects together answers from
other places. The goal is to not only point out how to do things but
why. I found that once I understood the why it was much easier to
understand what was going on and what I should do.
TL;DR: If you want to mix C++ and Blueprint your best bet is probably to follow something like Rama’s tutorial and then use the Execute_* functions in C++. This is because UE4’s Blueprint uses a message passing implementation of interfaces which is not what most C++ programmers are used to with classes.
Disclaimer: I am just figuring this out as well so some of the
following may be wrong (which is why it is a question!). Feel free to
answer and correct my many misunderstandings. Hopefully once we’re done we will have a clear and detailed explanation of how to uses classes and interfaces in C++ and Blueprint.
Question 1: How do I use interfaces in C++ and blueprint?
Answer 1: See various tutorials such as
The last one above was the one that gave me the final piece of the puzzle for my work.
Question 2: Why is all of this so complicated?
The short answer is because C++ allows multiple inheritance (which can be used to simulate interfaces) but not true interfaces while Blueprint allows interfaces but not multiple inheritance.
The long answer involves understanding the key difference between Blueprint and C++. Your C++ code sees the core UE4 C++ code via headers and so it can reference and call all of the UE4 C++ functions. Anything implemented in Blueprint has no C++ header files and so you can’t directly reference Blueprint created things from C++.
Let me repeat that last sentence because it took me a long time to understand the implications yet once I did everything made much more sense: Anything implemented in Blueprint has no C++ header files and so you can’t directly reference Blueprint created things from C++.
If you think about it Blueprint cannot be generating C++ headers and compiling them on the fly. If it did, you couldn’t have the quick and easy workflow you get in Blueprint because you would sometimes have to quit and restart the engine just like you do when changing C++ headers. Thus Blueprint extends the C++ classes (either the core UE4 classes or your own C++ classes) but does not generate new C++ headers.
So the only way you can call Blueprint code from C++ is by doing one of the following:
- Create a C++ class which defines a method that Blueprint extends and overrides. For example, you create class Foo with method Bar that Blueprint extends into class Baz and overrides the Bar method of Baz. In a C++ function you can be given a Foo*MyItem which actually points to a Bar and by calling MyItem->Baz(…) you will end up calling the Blueprint code.
- Create an interface in C++ which is implemented in Blueprint. For example, you create IFooInterface in C++ and implement that interface in Blueprint. You are then passed something like a UObjectMyItem or AActorMyItem in C++ and you do “the right thing”.
Let me expand on what I think is going on in 2 above because it confused me for a long time. Imagine you have a Bar class defined in Blueprint which inherits from AActor and implements the IFooInterface and you are given an AActor*SomeActor in C++ which you know points to a Bar object. If you want to call the DoSomethign method of the IFooInterface you naturally want to do something like:
IFooInterface* MyFoo = Cast(SomeActor);
This will fail. This confused me for a very long time. It fails because a the Bar class in Blueprint DOES NOT INHERIT FROM IFooInterface. Yes it implements the same functions as IFooInterface but because UE4 didn’t know about your IFooInterface class when it was compiled, their AActor cannot inherit from IFooInterface and so the Bar defined in Blueprint inherits from AActor (because Blueprint does not allow multiple inheritance). Even if you try
IFooInterface* MyFoo = (IFooInterface*) SomeActor;
things will fail for the same reason. Fundamentally SomeActor does not inherit from IFooInterface even though it implements the same methods.
The solution is basically message passing. UE4 uses the GENERATED_IINTERFACE_BODY() macro which you call in the IFooInterface definition to add the Execute_* methods as static methods of your class. What Execute_DoSomething does is basically send a message to a UObject and says “Please see if you claim to implement the methods in IFooInterface and if so call the DoSomething method.” This is kind of like how classes work in languages like python or Objective C or Smalltalk but not how classes generally work in C++ (which is why I found everything so confusing).
Once again TL;DR: If you want to mix C++ and Blueprint your best bet is probably to follow something like Rama’s tutorial and then use the Execute_* functions in C++. This is because UE4’s Blueprint uses a message passing implementation of interfaces which is not what most C++ programmers are used to with classes. If you try to use Cast<> or InterfaceCast<> things may not work as you expect.
To Epic: did I understand this correctly or can you correct me where I am wrong?