Grand unified C++/blueprint cast interface explanation

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 '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?

Answer 2:

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:

  1. 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.
  2. 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 '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?

Thanks,
-X

1 Like

You may want to post to the forums as well, when I have something “big” that this as a massive explanation or how to, that is a good place to put it.

Can you please view my question here and help me out? It seems that you might know how to solve my dilemmas.

Hey -

I wanted to comment on a few parts of your post for clarification:

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. 

This is both accurate and the best practice to use. Defining base behavior in code and overriding that behavior in a blueprint based off of your code allows for easy communication between code and blueprints.

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.

This is a bit confusing to . Foo* MyItem points to Foo and allows you to call the Bar method associated with the specific MyItem. MyItem->Baz will fail because Baz doesn’t exist in 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 UObject*MyItem or AActor*MyItem in C++ and you do "the right thing".

If you create an interface in code there are two ways to implement it in blueprints. If the blueprint is based on a custom class, you can use multiple inheritance to inherit the interface into the code class. The other option is to open the class defaults of the blueprint and add the interface directly to the blueprint. In both cases, you can access the functions inside the interface from the blueprint. As for being passed an UObject* or AActor*, this would likely be based on what interface function you’re using and if it requires an object or actor as input.

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.

This is correct. Basically when you attempt to cast it will follow the “is a” relationship of inheritance. Using the line of code above, it is basically saying “if SomeActor “is a” (inherits from) IFooInterface, then set it to MyFoo”. Since neither SomeActor nor Bar actually inherit from the interface the cast will fail.

ImplementsInterface - the “triple loop vs type casting” makes the call to the interfaces not very fast …

so in the end it may turn out that: implement the “Interfaces” (implementing some functional) via the component system for an actor may be cheaper.

it causes some difficulties in the development of architecture …

Check out the AnimMotionEffect function in ILyraContextEffectsInterface if you can access the Lyra project. It is a great example of how to have a native interface function that can be overridden both in c++ and in blueprint. You can also see how c++ class “AnimNotify_LyraContextEffects.cpp” called the interface function by using “Execute_AnimMotionEffect” and in B_Hero_Default, how the function is overridden and how its interface version is called directly.

1 Like