How to use interface between widget blueprint and data asset?

Hi, I have a DataAsset called “MissionDialog” that holds information about character dialog.

I’d like to call “MyMissionDialog->StartDialog( SomeWidget )” with a widget for the dialog to be presented upon.

SomeWidget is a Widget Blueprint that implements an interface to present the character dialog to the player.

The code below compiles with an error at “StartDialog(UWidgetBlueprintDialogInterface* …”

1>  [1/7] MissionDialog.gen.cpp
1>C:\Unreal Projects\stealthfps3\Intermediate\Build\Win64\UE4Editor\Inc\FPSGame\MissionDialog.gen.cpp(37): error C2664: 'void UMissionDialog::StartDialog(UWidgetBlueprintDialogInterface *)': cannot convert argument 1 from 'TScriptInterface<IWidgetBlueprintDialogInterface>' to 'UWidgetBlueprintDialogInterface *'
1>  C:\Unreal Projects\stealthfps3\Intermediate\Build\Win64\UE4Editor\Inc\FPSGame\MissionDialog.gen.cpp(37): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

Here is the interface:

// This class does not need to be modified.
UINTERFACE(MinimalAPI)
class UWidgetBlueprintDialogInterface : public UInterface
{
	GENERATED_BODY()
};

/**
 * 
 */
class FPSGAME_API IWidgetBlueprintDialogInterface
{
	GENERATED_BODY()

	// Add interface functions to this class. This is the class that will be inherited to implement this interface.

public:
	/** Please implement sub-classes with the dialog hidden from player to start. */
	UFUNCTION(BlueprintImplementableEvent, BlueprintCallable)
		bool SetDialogVisible(bool bDialogVisible);

	/** Indicate to the player that this character is speaking. */
	UFUNCTION(BlueprintImplementableEvent, BlueprintCallable)
		bool SetSpeakingCharacter(UMissionCharacter* NewSpeakingCharacter);

	UFUNCTION(BlueprintImplementableEvent, BlueprintCallable)
		bool SetListeningCharacter(UMissionCharacter* NewListeningCharacter);

	/** Will be called after each line of dialog (MissionDialogItem) is complete. */
	UFUNCTION(BlueprintImplementableEvent, BlueprintCallable)
		bool OnMissionDialogItemComplete(UMissionDialog* TheMissionDialog, FMissionDialogItem TheMissionDialogItem);

	/** Will be called after the MissionDialog is complete. */
	UFUNCTION(BlueprintImplementableEvent, BlueprintCallable)
		bool OnMissionDialogComplete(UMissionDialog* TheMissionDialog, bool bPlayedToCompletion);
};

Here is the DataAsset header:

UCLASS(BlueprintType)
class FPSGAME_API UMissionDialog : public UDataAsset
{
	GENERATED_BODY()

protected: 
	class TScriptInterface<IWidgetBlueprintDialogInterface> DialogWidgetWrapper;

public:

	/** Dialog lines to play in order. */
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
		TArray<struct FMissionDialogItem> MyDialogItems;

	/** Play character dialog, using the widget provided. */
	UFUNCTION(BlueprintCallable)
		void StartDialog(UWidgetBlueprintDialogInterface* DialogWidget);
};

And the implementation (comments are psuedo code for what I need to do next):

#include "MissionDialog.h"

#include "WidgetBlueprintDialogInterface.h"

void UMissionDialog::StartDialog(UWidgetBlueprintDialogInterface* NewWidget)
{
	//IWidgetBlueprintDialogInterface::Execute_SetDialogVisible(MyWidget, true);

	// Loop through dialog items and play them
	for (auto& MyDialogItem : MyDialogItems)
	{
		//IWidgetBlueprintDialogInterface::Execute_OnMissionDialogItemComplete(MyWidget, this, MyDialogItem);
	}

	// Notify UI
	//IWidgetBlueprintDialogInterface::Execute_OnMissionDialogComplete(MyWidget, this, true);
}

Here’s the excerpt from gen.cpp where the compile error happens:

	DEFINE_FUNCTION(UMissionDialog::execStartDialog)
	{
		P_GET_TINTERFACE(IWidgetBlueprintDialogInterface,Z_Param_DialogWidget);
		P_FINISH;
		P_NATIVE_BEGIN;
		P_THIS->StartDialog(Z_Param_DialogWidget);  // No user-defined-conversion ...
		P_NATIVE_END;
	}

I’ve tried several random things from google but can’t get the function parameters to compile. What’s the best way? Thanks!

Similar question: Reddit - Dive into anything

To make a parameter pass by reference
and still display as an input, use the
UPARAM() macro.

(Interface pointer as a parameter is not allowed.)
This little modification should work:

MissionDialog.h

void StartDialog(UPARAM(ref) TScriptInterface<IWidgetBlueprintDialogInterface>& DialogWidget);

MissionDialog.cpp

void UMissionDialog::StartDialog(TScriptInterface<IWidgetBlueprintDialogInterface>& NewWidget)
{
    IWidgetBlueprintDialogInterface::Execute_SetDialogVisible(NewWidget.GetObjectRef(), true);
    // ...

Wow! Thank you for showing the way. I took a different path - passing the DataAsset to the Widget instead. Thanks!