Branch 4.1 tag 4.1.1
I don’t know if it is an intended feature or a bug, but you cannot use InterfaceCast to expose class interfaces that are set in blueprint.
The code below is demonstrated a solution:
//Interface
#pragma once
#include "KinectFunctionLibrary.h"
#include "KinectListenerInterface.generated.h"
UINTERFACE(Blueprintable)
class UKinectListenerInterface : public UInterface
{
GENERATED_UINTERFACE_BODY()
};
class IKinectListenerInterface
{
GENERATED_IINTERFACE_BODY()
public:
UFUNCTION(BlueprintImplementableEvent, Category = NUI)
void ReciveBody(const FBodyFrame& BodyFrame);
};
//Event Dispatcher
void KinectEventDispatcher::DispatchEvent(){
FBodyFrame Frame = KinectSensor::Get().GetBodyFrame();
for (TObjectIterator<AActor> It; It; ++It) //Iterate over all actors
{
IKinectListenerInterface* ListenerInterface = NULL;
//Try InterFaceCasting
IKinectListenerInterface = InterfaceCast<IKinectListenerInterface>(*It);
//Problem/Bug/Feature? ListenerInterface is null, Event is not triggered
if (ListenerInterface)
ListenerInterface->Execute_ReciveBody(Frame);
//Solution: Triggers the event
if ((*It)->GetClass()->ImplementsInterface(UKinectListenerInterface::StaticClass())){
IKinectListenerInterface::Execute_ReciveBody((*It), Frame);
}
}
}
Sorry if I was unclear, in my code lines 36 to 43 are commented out and they are the reason I reported this bug.
Lines 46 to 50 are the solution to the problem I had in lines 36 to 43.
This snippet is the event dispatcher part of my Kinect plugin.
The goal of this code is to make my plugin native code “free” so everyone could use it without the need to see native code.
To achieve that I created an Interface IKinectListenerInterface which can be implemented inside the editor by any class that the user wants to receive events from the Kinect.
While exposing native interfaces to blueprints is pretty much straight forward the other way using InterfaceCast method described here:
on an Blueprint generated class returns null.
I hope that explains my report better.
Hi . I am little unsure about exactly what you are trying to do in a couple lines of your code sample. In line 36, it looks like you are creating a pointer named ListenerInterface, and setting the value to NULL. Then, in line 42, you are checking the see if ListenerInterface contains a valid value, which it does not since it is still NULL, so the following line never triggers.
Is your InterfaceCast in line 39 supposed to be updating the value stored in ListenerInterface? If you can clarify what those lines are trying to do, I can look into this a bit more for you.
Thank you for the clarification. I will continue looking into this for you. I am still a little unsure where ListenerInterface is being set to a value other than NULL, but I think I have what I need to investigate this.
I saw where you had declared the pointer and set it to NULL. I was just unsure where the pointer’s value was being changed to something else so the if check would work. I have reached out to one of our developers for some insight into this issue. I hope to receive some feedback from him within a few days.
If you’re using a BP interface, you need to use ScriptInterfaceCast instead of an InterfaceCast. You can check out the difference in Casts.h, where the two functions are defined.
The root of the problem with using the InterfaceCast is that it’s looking for a native entry point for the interface. But, since it’s implemented in BP, there is no native entry point, and you need to use the ScriptInterfaceCast to properly set things up.
However, the best way to use interfaces is with the IMyInterface::Execute_MyFunction, because that handles both the native and BP cases via the same path.
Thanks!
But if you’ll look at lines 46-50 in the code in the original post I have already proposed a solution in the bug report using IMyInterface::Execute_MyFunction, I reported the bug after finding that workaround
+1 for the “Why” explanation. I was looking at the Strategy example and wondering if there was a reason to prefer the IMyInterface::Execute_MyFunction approach over an InterfaceCast and now I know there is and why. The why is pretty important for really understanding something.
Casts were overhauled in version 4.6 to simplify their use. Part of that change was the removal of ScriptInterfaceCast(). From the version 4.6 release notes:
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.
If you are having some trouble with casting, please submit a new question since casting has changed significantly from when this question was originally asked.