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"

Cannot cast to C++ interface in Blueprints

While I can test if a particular object implements an Interface in blueprints I cannot cast that object to that interface and use it as that interface. Under the circumstances I am overriding functions within the blueprints I will NOT have the concrete version of that object, they are being sent in as base objects such as AActor or UObject.

I'm building the system of interfaces to orchestrate how seemingly unrelated Actor objects communicate with each other. I've build the interface functions to take in any AActor object and test of that Actor has the appropriate interface for performing actions on. This works beautifully in C++. However Blueprint seems to be a different beast.

So Lets say I have two Interfaces:

 class UInteractingAgent: public UInterface
 {
     GENERATED_UINTERFACE_BODY()
 }

 class IInteractingAgent
 {
     GENERATED_IINTERFACE_BODY()
 
     void SetPendingInteractable(AActor* interactable) = 0;
     void Pickup(AActor* pickup) = 0;
     void Damage(int amount) = 0;
 }

and

 class UInteractableActor: public UInterface
 {
     GENERATED_UINTERFACE_BODY()
 }
 
 class IInteractableActor
 {
     GENERATED_IINTERFACE_BODY()
 
     void IInteract(AActor* instigator) = 0
 }

So InteractingActor performs a scan for anything in view. If it finds an actor that is any Actor in view and attempts to it to the InteractingAgent's PendingInteractable (which is an Actor pointer) using the function SetPendingInteractable and passes that Actor into that function where it tests if that Actor has the IInteractableActor Interface.

 void MyInteractingAgentCharacter::SetPendingInteractable(AActor * actor)
 {
     IInteractableActor * interactable = InterfaceCast<IInteractableActor>(actor)
     if(interactable)
     {
     this->pendingInteractable = interactable;
     }
 }

Then if the user presses the interact button, the InteractingAgent's Interact function is fired passing the PendingInteractable into that function where it is cast once again to an IInteractingAgent using an interface cast where it's interact function is called passing the Pawn in as the instigator as an actor which it is then interface ast

 void MyInteractingAgentCharacter::Interact()
 {
     if(this->pendingInteractable != NULL)
     {
         IInteractableActor * interactable = InterfaceCast<IInteractableActor>(this->pendingInteractable);
         interactable->Interact(this)
     }
 }

 void MyInteractableActor::Interact(AActor* instigator)
 {
     if(instigator)
     {
         IInteractingAgent * agent = InterfaceCast<IInteractingAgent>(instigator);
         if(agent)
         {
             agent->Damage(10);
         }
     }
 }

Basically I have certain functions that will be overriden in blueprint. Because the interactions can happen between Actor and Actor or Actor and Pawn, or UObject and Actor and Pawn. Since these are the basic Subclasses of all UE4 objects the interfaces expect the least common denominator of the three (somethings will never be on things that are not actors so the least common denominator is Actor). So in blueprint I need away to cast an UObject, Actor, or Pawn to the desired Interface to work with it... however that functionality does not seem to exist...

Technically I could Cast to every Base Class of my own within blueprints but then that somewhat defeats the entire purpose for using Interfaces...

Product Version: Not Selected
Tags:
more ▼

asked Nov 15 '14 at 04:50 PM in Bug Reports

avatar image

ArcainOne
499 32 25 57

avatar image Tim C ♦♦ STAFF Nov 18 '14 at 05:16 PM

Hi ArcainOne,

I will be looking into this issue. I did have some clarification questions for you, though.

  • What version of the Engine are you using?

  • Are you using a version of the Engine that was installed by the Launcher, or did you build the Engine from source code?

  • Could you provide the exact steps you are following when creating and implementing your interface classes?

avatar image ArcainOne Nov 18 '14 at 09:02 PM

Hello Tim,

I am currently using the 4.5 version of the engine installed from launcher.

To Create a new Interface I usually directly add the .h and .cpp files to my project from inside Visual Studio, Aptly named "MyGameInterface.h"

The following is a direct copy of the InteractableActorInterface.h

 #pragma once
 
 #include "GameFramework/Pawn.h"
 #include "InteractableActorInterface.generated.h"
 
 /** 
 * Class required to support Interface Casting within the Unreal Engine System.
 */
 UINTERFACE(Blueprintable, MinimalAPI)
 class UInteractableActorInterface : public UInterface
 {
     GENERATED_UINTERFACE_BODY()
 };
 
 
 /** 
 * InteractableActorInterface is an interface implemented by all objects within the game world
 * that can be interacted with by a Pawn and Player.
 */
 class IInteractableActorInterface
 {
     GENERATED_IINTERFACE_BODY()
 
     /** 
     * Performs interaction on the object and supplies the instigator who triggered the action.
     */
     virtual void Interact(APawn * instigator) = 0;
 
     /** 
     * Sets the proper properties for the instigator to alert the player or AI 
     * that the item is available for interaction.
     */
     virtual void PrepareInteraction(APawn * instigator) = 0;
 
     /** 
     * Get a string that displays the interaction message.
     */
     virtual FText GetInteractionMessage() = 0;
 };

The following is a direct copy of the InteractableActorInterface.cpp

 #include "MyGame.h"
 #include "Item/InteractableActorInterface.h"
 
 UInteractableActorInterface::UInteractableActorInterface(const class FPostConstructInitializeProperties& PCIP) : Super(PCIP)
 {
 }
avatar image ArcainOne Nov 18 '14 at 09:25 PM

I apologize the next part get's a bit wordy, I am more than willing to answer any questions if you have any.

Currently most of the implementation of the blueprint is occuring in C++ on the base object level. Then the rest of the work will be done in blueprint as concrete objects are made from these base C++ classes with functionality added at specific points.

Every "InteractableActor" in the game implements this interface, be it another NPC, A Trigger button, a Pickup Item, or a Treasure Chest. The idea is when the Player get close enough to interact with one of these things in the game world a message "Press E to [Open, Pickup, steal, etc]" appears. They Press the E button and they perform a what ever interaction the object is designated to perform.

Rather than attempt to Cast to InteractableNPC, InteractableTrigger, InteractablePickup, and InteractableItemContainer classes It would be preferable to simply cast to IInteractableActor instead.

avatar image ArcainOne Nov 18 '14 at 09:48 PM

To attempt to really clarify these are the exact steps. Trying to provide as much information as I can hopefully this is me just not knowing what I'm doing haha.

  1. Create Interface .h and .cpp files in VS

  2. Define UInterface

  3. Define IInterface (as Pure Abstract Class)

  4. Create Actor or Pawn object via the Editor "Add Code to Project" in C++

  5. Define Methods of Actor or Pawn in C++

  6. Multiple Inheritance the IInterface and implement in Actor or Pawn in C++

  7. build and Reload Editor

  8. In a Blueprint that interacts with the Actor or Pawn attempt to Cast that Object to IInterface

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

3 answers: sort voted first

After EXTENSIVE research on this matter I finally solved it, though it was far form easy and there still exists some excentricities. Twiddle was not far off, but there was a gap in my own knowledge that was answered by pure luck of me discovering an Unreal Engine Interface that I could hook into through blueprints. After spelunking through the engine code I found the key to this riddle in the IGameplayTagAssetInterface found under the Runtime/GameplayTags/Classes folder.

So This solution is specifically well suited if you have multiple objects utilizing a different base object. In my case the interface will be applied to AActor types and ACharacter types, both share the AActor as a base class which allows my interface to pass round AActor types and InterfaceCast them to the proper interfaces in the implemented of the functions.

MyInterface.h

 UINTERFACE(Blueprintable, meta=(CannotImplementInterfaceInBlueprint))
 class UMyInterface : public UInterface
 {
     GENERATED_UINTERFACE_BODY()
 };
 
 class MYGAME_API IMyInterface
 {
     GENERATED_IINTERFACE_BODY();
 
 
     UFUNCTION(BlueprintCallable, Category = "My Interface")
     virtual AActor * GetSomeActor();
 
     UFUNCTION(BlueprintCallable, Category="My Interface")
     virtual bool SomeTestFunction(bool IsSomething);
 }

MyInterface.cpp

 /// Interface constructor here stuff ...

 AActor * IMyInterface::GetSomeActor()
 {
     unimplemented();
     return NULL;
 }

 bool SomeTestFunction(bool IsSomething)
 {
     unimplemented();
     return false;
 }

MyActor.h

 class AMyActor : public AActor, public MyInterface
 {
     UFUNCTION(BlueprintCallable, Category = "My Interface")
     virtual AActor * GetSomeActor() override;
 
     UFUNCTION(BlueprintCallable, Category="My Interface")
      virtual bool SomeTestFunction(bool IsSomething) override;
 };

MyActor.cpp

 AActor * MyActor::GetSomeActor()
 {
    AActor * returnActor = NULL;

    // Some code here to do things and get an actor and set returnActor

     return returnActor;
 }

 bool MyActor::SomeTestFunction(bool IsSomething)
 {
    bool returnBoolean = false;

    // do some stuff and test some stuff set returnBoolean

     return returnBoolean;
 }



You can pretty much do anything you want with this setup except the major drawback is that this interface CANNOT be implemented in blueprints. It just so happends that my solution does not need that at the level I am working with. However if you want to overcome that drawback I suggest trying to build a second interface that can be blueprint implementable that is called by your non-blueprint implementable interface

So you'd have MyInterface and MyImplementableInterface that has functions and events that are called from MyInterface (at least from the implementing class).

So now that you have this interface built, your base classes will implement the interface and then from blueprints you will need to call functions from it. In blueprints this is a bit different than I had expected but it works none-the-less. In any blueprint right click (without having any line drawn out) and look for a category called "Interface Messages". This is where you interfaces functions will be kept under what ever category you gave them.

Below is a screen show of how that will look with a few annotations.

alt text

Basically these "Interface Messages" take as the first parameter any object in the game and attempts to cast and call the function from that "target" object. If it fails it does so silently, if it succeeds then all is good. I suggest prefixing any one of these calls with a "Implements Interface" node in case you have any thing down the chain of events that require that that object actually implement the interface.

I hope this helps anyone else out there.

more ▼

answered Dec 01 '14 at 06:22 PM

avatar image

ArcainOne
499 32 25 57

avatar image Tim C ♦♦ STAFF Dec 03 '14 at 10:40 PM

I am glad to hear that you were able to find a solution that works for you, though I still think this should probably work a little more smoothly. I did want to make sure you were aware that the new version 4.6 that was released today does have some improvements specifically related to interfaces and casting:

Simplified Casting

Easily cast between Unreal classes using the improved Cast() function. You can even cast between interfaces and classes. We also now support using dynamic_cast to cast between Unreal types, if you prefer that.

and:

InterfaceCast has been deprecated - Cast or dynamic_cast should be used instead.

I would certainly be interested in finding out if some of these changes help with the issues you have been experiencing.

avatar image ArcainOne Dec 04 '14 at 05:59 PM

Tim,

I would LOVE this to be smoother as well and appreciate any work you guys and gals at epic put into making interfaces (and C++ coding for that matter) a bit more awesome. Interfaces are powerful things and highly useful.

So far my only remaining problem with interfaces is, even though this solution works for now it still has the problem that I cannot implement my interface in blueprints, and I must make a C++ base class for it. It's a minor irritation but if I am working on a team and my designer is lacking C++ knowledge he cannot prototype anything that uses that interface in Blueprints (with out an already established base class).

I am upgrading my project to 4.6 today and look forward to utilizing the new programming features. Thank you for your help!

avatar image Xarol Apr 18 '15 at 01:55 AM

Tim: It sounds like ArcainOne is saying that if a Blueprint implements a C++ interface then you can't cast a AActor* to the interface in C++. Is that right? That seems to be a huge limitation interfaces.

Thanks to both of you.

avatar image ArcainOne Apr 18 '15 at 06:48 AM

Hello Xarol,

Nope, you should be fine in C++. Using the Cast(myActor) you can cast an AActor pointer to your interface in C++.

My issue was that once I built an interface in C++, I cannot implement that interface in a new Blueprint Class.

So if I created an MyTestPawn in Blueprints derrived from Pawn I could not add my interface to it. Now I still have not tested this if it is true or not as I am currently in the drudges of coding, not designing. So I may be wrong. the "CannotImplementInterfaceInBlueprint" meta specifier seems to indicate otherwise.

avatar image ArcainOne Apr 18 '15 at 06:56 AM

Also the problem you where probably referring was probably the fact that UE4 Editor does not understand the Interface Object. It seems to understand the Interface functions and creates static nodes of those functions. Normally this is not an issue but if you have an Interface function that you want to return different Interface or take in an interface as a parameter, UE4 will not recognize it in the editor, and I think the compile may not work either... been a while since I've tried it.

To get around it, any time you want to have a function that takes in or returns another interace object, you need to reduce it to it's lowest common class within UE4.

As an example you have InteraceA which is only applied to AActor objects. Then you have InterfaceB that only uses objects that implement InterfaceA.

Unfortunatly you can't write your code as

 void MyFunction(IInterfaceA * interfaceA)

you have to write it:

 void MyFunction(AActor * interfaceA)

then inside your function check to see if that AActor implements the interface

 void IInterfaceB::MyFunction(AActor * interfaceA)
 {
     IInterfaceA * myInterfaceA = Cast<IInterfaceA>(interfaceA)
     if(myInterfaceA)
     {
         // do stuff
     }
 
 }


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

Ok, so the issue here is that you aren't marking your functions up correctly so that they can be exposed to Blueprint. Once that is done you will see some Interface Message nodes that show up in the context menu that will transparently handle casting to the interface class and calling functions from it.

Declare your functions like so:

 UFUNCTION(BlueprintImplementableEvent,BlueprintCallable, Category = Interaction)
          void SetPendingInteractable(AActor* interactable);

If you want to define a default implementation in native code you should take a look at BlueprintNativeEvent instead of BlueprintImplementableEvent:

 /// This function is designed to be overridden by a blueprint, but also has a native implementation.
 /// Provide a body named [FunctionName]_Implementation instead of [FunctionName]; the autogenerated
 /// code will include a thunk that calls the implementation method when necessary.

Note the absence of virtual - marking the function up as Implementable involves the generated code including a stub that calls the correct Blueprint functionality.

more ▼

answered Nov 19 '14 at 12:37 AM

avatar image

twiddle
1.5k 55 36 73

avatar image ArcainOne Nov 19 '14 at 04:36 AM

I really wanted it to be so Twiddle haha. I tried it out but my Interface is a Pure Virtual Class with no implementation. If i decorate the function with BlueprintImplementableEvent or Callable I get an Error

error: In InteractingAgentInterface: BlueprintImplementableEvents in Interfaces must not be declared virtual.

Because this interface needs to be implementable in C++ the functions must be virtual. I don't really have plans on implementing these interfaces IN blueprint but I need Blueprint to Cast to them... seems to be a tricky thing to do.

avatar image twiddle Nov 19 '14 at 04:49 AM

Have you tried BlueprintNativeEvent, and implementing Func_Implementation as a function that contains the actual functionality? I'm just running a test to see if you can implement Func_Implementation in a derived class, but if that works I think it would give you the functionality you desire without having to explicitly mark your original function as virtual. It looks like if you use BlueprintNativeEvent, then the auto-generated prototype for your FuncName_Implementation function does have the virtual keyword, so I think you should be good with that.

Eg: this is part of some autogenerated code from UHT:

 virtual void ServerTryActivateAbility_Implementation(...)

You'll probably need to provide an empty stub rather than a pure virtual function in your interface in order to keep the autogenerated thunk that calls it happy, but nevertheless, I don't see how it wouldn't work.

avatar image ArcainOne Nov 19 '14 at 05:41 AM

Unfortuantly I do not think this will work. I answered a very similar question with someone trying to Override the Implementation of a BlueprintNativeEvent. Currently the way I have been handeling Overriding of a C++ function that I also want to possibily be overriden in a Blueprint is to create two functions

 UFUNCTION(BlueprintCallable, Category="MyFunctions')
 virtual void MyFunction()
 
 UFUNCTION(BlueprintNativeEvent, Category="MyFunction")
 void OnMyFunction()

I do know that there seems to "possibly" be a way to create your own custom thunk in UE4 using one of the function specifies... I think it is CustomThunk lol but I have absolutely no idea how that works or how to do it.

avatar image twiddle Nov 19 '14 at 05:55 AM

What was the actual issue that you encountered when trying it? There is CustomThunk, yes, but I don't see why you couldn't override the Implementation thunk if it's marked as virtual.. I will try it myself soon, but I'm hip-deep in squishing another bug at present.

avatar image ArcainOne Nov 19 '14 at 06:09 AM

I was not able to test it at the moment, But I am not sure if you can override an Implementable function even if it is marked virtual. I helped someone else with that same issue where he was trying to override an BlueprintNativeEvent but his C++ sub classed override was not being called. That was the solution I came up with. granted that was version 4.4 but we where having issues with it. I thought it was just how the UBT worked.

If that IS true however that would make so much of my life easier as I have been utilizing that method of double declaring functions to be overridable in C++ and Blueprints

avatar image twiddle Nov 19 '14 at 10:12 AM

Good news - it works. I just added the following to a Character subclass:

 virtual void OnJumped_Implementation() override
 {
     Super::OnJumped_Implementation();
     GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, TEXT("Overridden Onjump_impl"));
 };

I got the text as well as a breakpoint in the parent class' function being hit.

You gotta make sure you're overriding FunctionName*_Implementation* rather than just FunctionName. I suspect this might be why your previous attempt failed.

avatar image ArcainOne Nov 19 '14 at 03:54 PM

That is good news. I'll give it a shot, though it urks me to utilize an implemented class... I come from a long ancient line of "Multiple inheritance is evil" disciplines and it's a bit ingrained... I have an exception for Pure Virtual Classes because of the lighter overhead. but if it works it works. I'd still like to see a Pure Abstract Class work with this in the future though. UE4 may need a new UFUNCTION Decorator to indicate such a thing.

avatar image ArcainOne Nov 28 '14 at 05:52 PM

I finally got a chance to try this out but the results where quite upsetting. The Interface was implemented and compiled in C++ but I still was unable to Cast To it via Blueprints. Worst, in blueprints the normal functions defined in the interface where not accessible... only options for the"Implementation" functions where there. My Implementation follows

InteractingAgentInterface.h

 class IInteractingAgentInterface
 {
 UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Interacting Actor")
     AActor* GetPendingInteractableObject();
 }

InteractingAgentInterface.cpp

 /**
 * Get the pending interactable if one exists
 * @return AActor pointer to the interactable object
 */
 AActor* IInteractingAgentInterface::GetPendingInteractableObject_Implementation()
 {
     unimplemented();
     return NULL;
 }

MyPawn.h

 class MyPawn : public ACharacter, public IInteractingAgentInterface
 {
 /**
     * Get the pending interactable if one exists
     * @return AActor pointer to the interactable object
     */
     UFUNCTION(BlueprintPure, Category = Interactions)
         virtual AActor* GetPendingInteractableObject_Implementation() override;
 
 AActor* pendingInteractableObject;
 
 }

MyPawn.cpp

 /**
 * Get the pending interactable if one exists
 * @return AActor pointer to the interactable object
 */
 AActor* AAeonCharacter::GetPendingInteractableObject_Implementation()
 {
     return this->pendingInteractableObject;
 }

In the Blueprints attempting to cast to IInteractingAgentInterface alt text

In Blueprints attempting to call HasPendingInteractableObject or GetPendingInteractableObject

alt text

The warning on both those nodes says It cannot find that function.

avatar image twiddle Nov 19 '14 at 06:29 PM

If you look at the definition for BlueprintNativeEvent, it is documented there that you'll be actually implementing FuncName_Implementation and leaving FuncName to the code generation. I should also note - I didn't actually test with a pure virtual base - so perhaps you should try that and see how you go. I merely tested that a subclass can override the _Implementation function from a parent, but in my test case Character did have an empty stub already.

avatar image ArcainOne Nov 19 '14 at 08:24 PM

using a Pure Virtual Base Class with a BlueprintNativeEvent function does not work nor does it work for BlueprintImplementableEvent because it is composed of Pure Virtual Functions. You have to make the interface basic virtual functions that do not require overriding in the sub classes, which is what I want out of the C++ sub classes. I want to force a developer using the system to have to implement the interface explicitly.

However It is a philosophical problem really for me. I like the C# specification of One base class and all the interfaces you want and I tend to carry that over utilizing Abstract Base Classes composed entirely of Pure Virtual Functions with no properties or fields and it MUST be implemented by the inheriting class... I've no idea if there is a performance benefit or penalty for it but it feels cleaner haha.

A new Specifier like BlueprintInterfaceEvent specifically for Abstract Base Classes would be nice. Technically the BlueprintNativeEvent does cover it but it's a bit... non-intuitive from the C++ side... maybe I'm asking too much haha but it would be nice.

Technically Twiddle you have the way to do it until Epic changes this... and I do hope they change it :)

UPDATE

Actually though if you really wanted to get crazy with it you could build two interfaces... one for C++ implementation and one for Blueprint... but that's probably overkill, over engineering, over thinking, and most likely over complicating it... haha

avatar image twiddle Nov 19 '14 at 08:46 PM

Well, the issue is that any tags you provide like BlueprintImplementable, BlueprintNativeEvent etc, are used for automatic code generation, meaning that under-the-hood you are always getting some sort of concrete class being created regardless. If nothing else, the thunk that BlueprintNativeEvent creates has a concrete implementation which is calling your Func_Implementation function, so you'll never be able to have a pure virtual class that does this, only an abstract one.

I think some of the philosophical dissonance you are experiencing comes down to the fact that C++ doesn't have the concept of an interface as a first party object in the same way that C# does. As far as performance overhead goes, I'd say that factoring in C#'s compile-to-MSIL-then-interpret-bytecode-at-runtime approach, you'll probably see a similar overhead with interfaces vs multiple inheritance in the sense that there's still a vtable that helps to resolve function calls at runtime.

If you really want to force the developer to override your base implementation, my suggestion is to create a macro like CHECK_INTERFACE_IMPLEMENTED() that you can place in your base class. This macro would simply throw an exception with 'func x not implemented/overridden'.

I see from a quick look through the code base that AssertionMacros.h already has

 #define unimplemented()       { FDebug::AssertFailed( "Unimplemented function called", __FILE__, __LINE__ ); }

So my advice would be to use the approach I already mentioned, and simply put calls to unimplemented() in your default implementation.

avatar image ArcainOne Nov 20 '14 at 12:38 AM

All Agreed. But to be fair I thought that was what the UInterface was for, To be a representation of the IInterface within the blueprint system that defines the actual interface...

avatar image twiddle Nov 20 '14 at 12:42 AM

Take a look at this question one of my students asked a while back. It clarifies a little bit of the difference between the UInterface and IInterface. The latter is the thing which is actually used by the compiler to extend the vtable.

avatar image ArcainOne Nov 24 '14 at 08:33 PM

Well that makes since. While I still stand that the use of a Pure Virtual Class would be preferable... Using an Abstract Base Class and overriding the Implementation function is the way to go with UE4.

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

Thanks very much for this question. The question and the many answers helped me a lot with my interface issues and were a key part of me finally understanding what is going on.

I think you don't need two separate interfaces if you use the Execute_* forms. I tried to summarize what I think is going on with interfaces mixing C++ and Blueprint and why at https://answers.unrealengine.com/questions/214147/grand-unified-cblueprint-cast-interface-explanatio.html in case it would be helpful.

Thanks, -X

more ▼

answered Apr 18 '15 at 07:01 PM

avatar image

Xarol
353 21 32 39

(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