Cast always fails even though the object is a child of the the thing I am casting to.

Hello everybody,

I am trying to make a game in unreal engine and want to implement a crafting system. I have already implemented a Interaction system however when I look at the crafting table the Interaction Widget does not show up even though I set the widget class. Through debugging I have traced the error to the cast failing in this function called after the object is seen.

void UInteractionComponent::RefreshWidget()
{
	if (UInteractionWidget* InteractionWidget = Cast<UInteractionWidget>(GetUserWidgetObject()))
	{
		InteractionWidget->UpdateInteractionWidget(this);
	}
}

I don’t know why this would fail since in blueprints I have confirmed the widget class is a child of Interaction widget. Here is the constructor for Crafting Item.

AbaseCraftingItem::AbaseCraftingItem()
{

    PrimaryActorTick.bCanEverTick = true;

    SpawnMesh = CreateDefaultSubobject<UStaticMeshComponent>("SpawnMesh");
    SpawnMesh->SetCollisionResponseToChannel(ECC_Pawn, ECR_Ignore);

    SetRootComponent(SpawnMesh);

    InteractionComponent = CreateDefaultSubobject<UInteractionComponent>("InteractionComponent");
    InteractionComponent->InteractionTime = 0.f;
    InteractionComponent->InteractionDistance = 450.f;
    InteractionComponent->InteractableNameText = FText::FromString(DisplayName);
    InteractionComponent->InteractableActionText = FText::FromString("Open");
    InteractionComponent->OnInteract.AddDynamic(this, &AbaseCraftingItem::OnInteract);
    InteractionComponent->SetupAttachment(SpawnMesh);

}

I declare the widget class in blueprints.

I am new to to the Unreal Forums so if I am missing anything or have formatted my question wrong I would love the feedback. But any help would be greatly useful since I have spent weeks on this bug.

I am using unreal version 4.27

Thank you in advance,

void UInteractionComponent::RefreshWidget()
{
	UInteractionWidget* InteractionWidget = Cast<UInteractionWidget*>(GetUserWidgetObject());
	if (InteractionWidget)
	{
		InteractionWidget->UpdateInteractionWidget(this);
	}
}

Not sure but I would think the IF maybe testing the wrong value

???
Cast<UInteractionWidget*>

I tried this but it still did not worked when I tested the casting in blueprints it still failed.

Does InteractionComponent use a UWidgetComponent? And then does GetUserWidgetObject() retrieve the widget in the UWidgetComponent?

InteractionComponent is a UWidgetComponent and GetUserWidgetObject() does return a InteractionWidget.

And somewhere you are getting the widget bp and setting it in your InteractionComponent.
Something similar to:

InteractionComponent->SetWidget(myWidgetBp);

I declare the widget class in the editor should I try declaring it in C++?

GetUserWidgetObject() may return null

It doesn’t help that the documentation page is completely wrong for interfaces - but essentially if you implemented the interface in a Blueprint class you CANNOT use ‘Cast’, this only works for interfaces that are implemented natively.

If the functions are Blueprint Events, you are also not allowed to call them directly. They must be called via static “Execute_” functions that UHT will auto-generate.

See the following:

if (Object->Implements<UMyInterface>())
{
	IMyInterface::Execute_CustomFunction(Object, args...);
}
1 Like

Ok this makes sense the Widget has blueprint implementable events. I am just wondering why the Widget would show up for other Things? However I don’t exactly understand what you are recommending for the fix ill include the Widget component and Crafting Item if you could show me.

CraftingItem.cpp (552 Bytes)
CraftingItem.h (556 Bytes)
InteractionWidget.cpp (383 Bytes)
InteractionWidget.h (695 Bytes)

For those who were wondering here are the tests I ran.

it prints failed every time

here is the editor for the Base crafting Item

image

and
image

I did further testing and found that the Get user widget object returns null.

How would I fix this?

I think you can call InitWidget before calling GetUserWidgetObject.

Ok I tried to do this

void UInteractionComponent::RefreshWidget()
{
        UWidgetComponent::InitWidget();
	if (UInteractionWidget* InteractionWidget = Cast<UInteractionWidget>(GetUserWidgetObject()))
	{
		InteractionWidget->UpdateInteractionWidget(this);
	}
}

I’m not sure what to InitWidget could you show me? The above example did not work.