Download

Setting a blueprint variable from c++ actor

Hello,

I’m trying to set a variable on a widget from a c++ actor, I have a static mesh and I’m adding a widget to it.
The widget appears fine although in the wrong location however, I’m having issues while trying to set a variable in the widget, this is what I have.



planetMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Planet"));
//planet->SetCollisionProfileName(TEXT("StarCollision"));
RootComponent = planetMesh;

static ConstructorHelpers::FObjectFinder<UStaticMesh> StarAsset(TEXT("/Game/Planet_Creator_1_V2/Static_Meshes/SM_PlanetSphere_1"));

MyPopupWidget = CreateDefaultSubobject<UWidgetComponent>("PopupWidget");
static ConstructorHelpers::FClassFinder<UUserWidget> PopupWidgetObj(TEXT("/Game/Levels/System/W_SystemBillboard.W_SystemBillboard_C"));
if (PopupWidgetObj.Succeeded()) {
MyPopupWidget->SetWidgetClass(PopupWidgetObj.Class);
MyPopupWidget->SetWidgetSpace(EWidgetSpace::Screen);
MyPopupWidget->SetRelativeLocation(FVector(0.0f));
MyPopupWidget->SetPivot(FVector2D(-1.5, 0.5));

FName PropName = TEXT("PlanetName");
UProperty* Property = PopupWidgetObj.Class->FindPropertyByName(PropName);
if (Property)
{
FText* ptrValue = Property->ContainerPtrToValuePtr<FText>(PopupWidgetObj.Class);
if (ptrValue)
{
*ptrValue = FText::FromString(planet.planetName);
}
}

} else {
UE_LOG(LogTemp, Warning, TEXT("Popup widget could not initialize on InteractibleActor"));
}

if (StarAsset.Succeeded())
{
planetMesh->SetStaticMesh(StarAsset.Object);
planetMesh->SetRelativeLocation(FVector(0.0f));
planetMesh->SetWorldScale3D(FVector(1.0f));
}


and the error I am getting is:



Assertion failed: ((UObject*)ContainerPtr)->IsA(GetOwner<UClass>()) [File:E:\Epic Games\UE_4.25\Engine\Source\Runtime\CoreUObject\Public\UObject/UnrealType.h] [Line: 383]
'W_SystemBillboard_C' is of class 'WidgetBlueprintGeneratedClass' however property 'PlanetName' belongs to class 'W_SystemBillboard_C'
UE4Editor.exe has triggered a breakpoint.


I’m not really sure what this means or how to fix it any help would be appreciated.

Not sure if a property of BP can be modified in cpp. I usually define this property-to-be-modified in parent cpp class.Or you could just add implementable event which leads to modify property right inside the BP itself.

You are trying to set the value in the class.
“Container” is actually an instance of your widget object that you should use, not the class.

Thanks, I will give your suggestion of using a c++ parent of the widget ago although I’m sure it is possible the way I’m ‘trying’ to do it.

Sorry I’m not sure what you mean exactly I understand it’s trying to use the wrong class, but could you give an example on what you mean when you say the container?

Many thanks.

probably being daft, but I’m unable to set any properties when the parent is a c++ class as I’m struggling to cast back to it keeps coming up null



static ConstructorHelpers::FObjectFinder<UStaticMesh> StarAsset(TEXT("/Game/Planet_Creator_1_V2/Static_Meshes/SM_PlanetSphere_1"));

MyPopupWidget = CreateDefaultSubobject<UWidgetComponent>("PopupWidget");

static ConstructorHelpers::FClassFinder<UUserWidget> PopupWidgetObj(TEXT("/Game/Levels/System/W_SystemBillboard"));
if (PopupWidgetObj.Succeeded()) {

WSystemBillboard = PopupWidgetObj.Class;

MyPopupWidget->SetWidgetClass(WSystemBillboard);
MyPopupWidget->SetWidgetSpace(EWidgetSpace::Screen);
MyPopupWidget->SetRelativeLocation(FVector(0.0f));
MyPopupWidget->SetPivot(FVector2D(-1.5, 0.5));


USystemBillboard * WidgetBillboard = Cast<USystemBillboard>(WSystemBillboard);
WidgetBillboard->planetName = FText::FromString(planet.planetName);


} 

Thanks

What you are trying to cast is the class description, what you need to cast is the actual widget object instance. The widget object gets created by UWidgetComponent, and you can access it with GetUserWidgetObject(). So something like this should work:


USystemBillboard * WidgetBillboard = Cast<USystemBillboard>(MyPopupWidget->GetUserWidgetObject());

However you might not want to do this in the constructor, chances are that the widget isn’t created yet at this point (you created the WidgetComponent but the widget component will still have to create the UserWidget). If it must happen right away, you could override BeginPlay or PostInitializeComponents, or try calling MyPopupWidget->InitWidget() first.