x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

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

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 UObject*MyItem or AActor*MyItem 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?

Thanks, -X

Product Version: Not Selected
Tags:
more ▼

asked Apr 18 '15 at 06:53 PM in C++ Programming

avatar image

Xarol
353 21 32 39

avatar image ArcainOne Apr 19 '15 at 05:37 AM

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.

avatar image vikhik Sep 17 '15 at 05:01 AM

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

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

1 answer: sort voted first

Hey Xarol-

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 read. 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.

more ▼

answered Mar 09 '16 at 08:26 PM

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question