Download

TScriptInterface troubles

I’ve been using TScriptInterface so I can use an interface reference as a UProperty.

I can’t assign NULL without first typecasting to a known UObject class that implements the interface. It’s because things assigned to TScriptInterface must be UObjects that also implement the interface.

My code ends up looking like this:



//Casting to AWRPickup as a hack to get this to compile.  I just want to set the value to NULL.
TargetUsable = TScriptInterface<IWRUsableInterface>((AWRPickup *)NULL);


I even ran into the issue when I was trying to assign a pointer to my interface type to a TScriptInterface.

This can be solved by adding a constructor to TScriptInterface that just takes a pointer to the interface instead of a UObject pointer.



//was the result a usable object?
IWRUsableInterface * HitUsable = Cast<IWRUsableInterface>(HitResult.Actor.Get());

if (HitUsable)
{
	//Casting to AWRPickup as a hack to get this to compile.
	TargetUsable = (AWRPickup *)HitUsable;
}


The first issue is because the assignment operator is templated and can’t resolve the type from NULL. Just do:


TargetUsable = TScriptInterface<IWRUsableInterface>();

Your second issue is I think a fundamental limitation with UE4 interfaces. You can’t assign an interface pointer, you have to always have a UObject pointer. Creating a new constructor as you say might appear to get around it, but I’m sure will end up breaking the code, since the TScriptInterface needs to store a valid UObject pointer along with the interface pointer.

Ah of cource, use the default constructor to set it to NULL.

For the second thing, it could probably put an assert in there to make sure it’s casteable to a UObject.

Now I’m trying to figure out how to check if the interface reference is NULL in blueprint.
For now I ended up having to create a C++ Blueprint Library function that takes the interface and returns if it’s NULL or not by checking C++ side. Hopefully there’s a cleaner way.

For checking in blueprint whether an interface variable is pointing to NULL, cast it to an object and check the object with NULL:
a7ab844c6d4a9e83cd0f17a54862a2ee18089fcb.png

By the way, this is how I set a TScriptInterface and how I clear it, by calling both SetInterface and SetObject. Using your variable naming:



IWRUsableInterface * HitUsable = Cast<IWRUsableInterface>(HitResult.Actor.Get());
if (HitUsable)
{
	TargetUsable.SetInterface(HitUsable);
	TargetUsable.SetObject(HitResult.Actor.Get());
}




TargetUsable.SetInterface(NULL);
TargetUsable.SetObject(NULL);


I’m not sure if its the intended way to set and clear a TScriptInterface, but since TScriptInterface basically acts as a wrapper for the same object as a UObject pointer and IYourInterface pointer, I think this is alright.

How do you get that conversion node in Blueprint? For me if I try to check != it just creates the != node and fails to compile. I can’t even use a Cast to Object node since that still takes an object.

About the C++ though, that clears it up. I didn’t even see those functions because I was looking at the docs here: TScriptInterface | Unreal Engine Documentation

Didn’t think of looking at the super class functions: FScriptInterface | Unreal Engine Documentation

This makes everything better heh.

To get the conversion node drag off the interface variable and start typing To Object (Interface), that is the one you need. :slight_smile:

That worked.

Now I have another question. How do I make a variable with the interface type.

The interface type for me is passed in through an event. When I drag off of the input param pin there is no option to promote to variable. And when I try to create a new variable and specify its type the interface type doesn’t show up as a valid type when I try to enter its name in the search.

Make sure your UInterface C++ class is a BlueprintType:



UINTERFACE(BlueprintType)
class UInteractable : public UInterface


Info: BlueprintType | Unreal Engine Documentation

The docs still leave it a little unclear as to where we do and don’t reference the UInterface vs. the IInterface. Is the IInterface just there fore codegen or is it the other way around?