[4.8.0] - Cannot Cast UMG Widget To C++ Interface

Hey Guys,

I’m having an issue here trying to cast a custom UMG Widget that inherits an interface to that interface.

In code…

UINTERFACE()
class UChatWindowInterface : public UInterface
{
	GENERATED_UINTERFACE_BODY()
};

/**
* The IChatWindowInterface class is the actual interface class representation of the ChatWindowInterface.
*/
class IChatWindowInterface
{
	GENERATED_IINTERFACE_BODY()

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, Category = "IChatWindowInterface", Meta = (DisplayName = "Add Chat Text"))
	void AddChatText(const FText& ChatText);

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, Category = "IChatWindowInterface", Meta = (DisplayName = "Focus Chat Window"))
	void FocusChatWindow();

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, Category = "IChatWindowInterface", Meta = (DisplayName = "Show Chat Window"))
	void ShowChatWindow();

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, Category = "IChatWindowInterface", Meta = (DisplayName = "Hide Chat Window"))
	void HideChatWindow();
};

I then have this setup as an interface in the UMG’s Class Settings. (On another note, its odd that functions w/ no return type come up as Events). But I have those functions/events overridden in the Blueprint fine.

In code, I run through and iterate over all the UUserWidget’s currently in the level. When I attempt to use…

IChatWindowInterface* Interface = Cast<IChatWindowInterface>(SomeWidget);

… it always comes back as a nullptr reference. I’ve attempted casting to UChatWindowInterface, trying dynamic_cast, etc and it unfortunately can’t find it.

Is there something I’m missing?

Thanks Guys!

EDIT: As a note, I’m not using UInterface(MinimalAPI) since I read somewhere that if you want BPs to see the interface, to ignore that attribute.

Hi ,

The only time I’ve ever seen a cast return a nullptr is when the cast fails due to the object that is being used to cast is not of the same type as expected. Can you post the entire function that this line of code is part of along with (if it isn’t in there) the line of this ‘SomeWidget’ being defined?

Hey ,

I agree. Maybe it has to do with because its assigned to the Widget in the editor but let me give you my code and we’ll start from here. This is the snippet of code where I run through and try to find the ChatWindow UserWidget…

UWorld* World = GetWorld();
		for (TObjectIterator<UUserWidget> Iterator; Iterator; ++Iterator)
		{
			if (Iterator->GetWorld() != World)
				continue;
			else
			{
				UUserWidget* Widget = *Iterator;
    
				IChatWindowInterface* Interface = Cast<IChatWindowInterface>(*Iterator);
				if (UGameExtensions::IsValid(Interface))
					ChatWindow = Interface;
			}
		}

As a note, I have the ‘Widget’ variable just so when I debug, I can see what’s coming back

And in the BP Class Settings, I have the ‘Chat Window Interface’ set as an interface

So I just looked through the Visual Studio debugger and found that deep inside the Widget once I find the ChatWindow, I can see the ‘Interfaces’ array is empty.

For extra precaution, I just looked in the UMG BP but it still has the interface set.

EDIT: Another thing I just noticed is the Chat Window’s UObject name is simply “Chat Window” where as all other UMG Widget’s are coming back w/ the post-fix ‘_C_InstanceNumber’. Doubt that has anything to do with it but you never know.

I know almost 100% I can avoid this by creating another base class that inherits UUserWidget, add the interface to be inherited and re-parent the Widget to that new class but it’s probably better I figured this out just in case and also in the case it does have something to do w/ the engine.

I’ll let you know if I come up with anything else and thanks again.

Casting to an interface does not work with objects that are configured to implement an interface in blueprint only. More fundamentally in fact, you simply cannot get a pointer of IMyInterface* type to such an object. This has always been the case and is a pretty major drawback to using them. Personally I’ve avoided UE4 interfaces in the hopes that they would see some improvements, but there has been no sign of that happening.

One solution is exactly as you say in your comment. If you are able to create a C++ base class which inherits the interface, this is the cleanest way.

The alternative is documented here. This shows how to test an object for support and also call an interface function. In your code you seem to want to just store an interface pointer. Without making a C++ base you can’t do this directly, but you can test for the interface, and then store a UObject pointer. Later when you come to use it, you call the interface functions as shown on the wiki. For example:

IChatWindowInterface::Execute_ShowChatWindow(MyStoredUObjectPtr);

Clearly this isn’t ideal. It would be really nice if someone from Epic would weigh in on this situation. A lot of people have struggled with it, as can be seen here.

Wow , thanks for such a detailed response and taking your time to help make some sense of this.

I was wondering if it was something having to do with the engine since Interfaces. That’s a bummer but I noticed this article was posted back during 4.3, man.

, can you weigh in on this one? Also, can you check in w/ any devs and ask if Epic is going to spend any time improving how interfaces work in the engine any time in the near future?

Thanks and , thanks again for taking your time to fill me in that others have experienced this and pointing me to that article. It gives me some options on how to proceed.

Much appreciated! :slight_smile:

Hi and ,

From what I understand and have been told by others who are familiar w/ Interfaces in C++, there isn’t a way around doing it this way. The only option would be to inherit from the interface that you wish to cast to. Unfortunately there isn’t another way around this other than making another class just to do this which, from my perspective, would be a waste when you could inherit directly. I will look into getting more documentation written up that can explain how this particular element of the engine works.

Hope this helps,

Thanks for the response . For me, the issue is that the whole point of an interface is to abstract away from an object’s type - we neither know nor care what its type is, only that it implements the interface. But with the current approach, this isn’t possible - we need to know in advance that an object implements the interface in C++ (rather than in BP) in order to cast it.

Having thought about it, I can see that it is indeed probably impossible to find a way to cast a blueprint object implementing an interface on the C++ level. However, I believe it is at least possible to create some wrappers that would allow us to code this in a more intuitive way. I’m sending you a PM on the forums relating to this.

Regardless, some better documentation on interfaces would be much appreciated. Cheers.

Thanks for chiming in on this one Matt and much appreciated.

The only problem with that as mentioned is it unfortunately defeats the point of having an interface in the first place. Even if the type inherits the interface in Blueprints, it’s still inheriting on the parent level and should be able to be cast to regardless.

I would like to hopefully think this wouldn’t be impossible :slight_smile: but fingers crossed interfaces in UE4 get better down the line.

In worst case, it forces me to create a base class for anything I want to cast to in this case which isn’t that big of a deal, but would be nice if avoidable.

, keep us posted if your idea for use of a wrapper works.

In regards to the private message. I would recommend that you submit a pull request to have this wrapper added as it is related to actually editing source code to have this implemented. This would be the usual route for changes to be added via user suggestion when the user has a working prototype and it seems that you’re in this position.

That would be great if your idea works and best of luck. If you need a hand, I’d be glad to help tackle that one with you.

Hopefully there is a way to get access to the underlying UFUNCTION pointers from the BP type. I’d say go ahead and this resolved and I’ll keep my eyes peeled for any future updates to interfaces.

Thanks Matt on helping shed some light on this. It’s a bummer but the workaround isn’t that much more work and there is hope down the line.

It has been mentioned that some of the Epic Devs are looking at ways to make Blueprints compile down to C++ and if that ends up making its way in eventually, then it absolutely will be possible at that point for sure.

Thanks guys and best of luck of the wrapper :slight_smile: