Hello my fellow coders - I am in need of an assistance for this problem
I have MyPlayerController.c (.h), MyGameHUD.c (.h) and MainUIWidget.c (.h)
MyGameHUD is custom class default HUD for MyPlayerController in MyGameMode MainUIWidget is custom class - simple widget with few buttons MyPlayerController is custom class
I want to spawn actor on MyPlayerController when button on MainUIWidget is pressed
Until now I got only access violations because it seems that UWorld is not accesible from MainUIWidget
MainUIWidget.h
UCLASS()
class MY_API UMainUIWidge: public UUserWidget
{
GENERATED_BODY()
void ConstructBuilding(FString BuildingName);
MyPlayerController* PlayerControllerPtr;
UPROPERTY(EditDefaultsOnly, BluePrintReadWrite, Category = "Buttons", meta = (BindWidget))
class UButton* Button_1;
};
MainUIWidget.cpp
UMainUIWidget::UMainUIWidget(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
PlayerControllerPtr = Cast<AMyPlayerController>(GetOwningPlayer());
}
void UMainUIWidget::NativeConstruct()
{
Super::NativeConstruct();
// Bind delegates here
Button_1->OnClicked.AddDynamic(this, &UMainUIWidget::SendSignalBuildBuildingBP_Button1);
}
void UMainUIWidget::ConstructBuilding(FString BuildingName)
{
PlayerControllerPtr->ConstructBuilding(FString BuildingName);
}
void UMainUIWidget::SendSignalBuildBuildingBP_Button1()
{
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, TEXT("Signal to build!"));
ConstructBuilding(FString("SmallHouse"));
}
MyGameHUD.h
class MY_API AMyGameHUD : public AHUD
{
GENERATED_BODY()
public:
AMyGameHUD ();
virtual void Tick(float DeltaSeconds) override;
virtual void BeginPlay() override;
virtual void DrawHUD() override;
void DrawUI();
UPROPERTY(EditAnywhere, BluePrintReadWrite, Category = "Widgets")
TSubclassOf<UUserWidget> UMainUIWidgetClass;
private:
UMainUIWidget* UMainUIWidget;
MyGameHUD.cpp
MyGameHUD::MyGameHUD()
{
PlayerControllerPtr = Cast<AMyPlayerController>(this->GetOwningPlayerController());
}
void MyGameHUD::BeginPlay()
{
Super::BeginPlay();
DrawUI();
}
void MyGameHUD::DrawUI()
{
if (UMainUIWidgetClass)
{
UMainUIWidget= CreateWidget<UMainUIWidget>(GetWorld(), UMainUIWidgetClass);
if (UMainUIWidget)
{
UMainUIWidget->AddToViewport();
}
}
}
void MyGameHUD::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
}
void MyGameHUD::DrawHUD()
{
Super::DrawHUD();
}
Expected behavior is to:
Behavior now:
Any ideas please?
EDIT -> added MyPlayerController
MyPlayerController.cpp
AMyPlayerController::AMyPlayerController()
{
DefaultMouseCursor = EMouseCursor::Crosshairs;
bShowMouseCursor = true;
bEnableClickEvents = true;
bEnableMouseOverEvents = true;
// pre-load class for SpawnActor
static ConstructorHelpers::FClassFinder<BuildingClass> SmallHouseBPClass(TEXT("Reference/To/Blueprint/Class/BP.BP_C"));
SmallHouseClass = SmallHouseBPClass.Class;
}
void AMyPlayerController::ConstructBuilding(FString BuildingName)
{
if (BuildingName.Compare("SmallHouse") == 0)
{
GetWorld()->SpawnActor<BuildingClass>(SmallHouseClass);
}
}
AMyPlayerController.h
UCLASS()
class AMyPlayerController : public APlayerController
{
GENERATED_BODY()
public:
AMyPlayerController ();
void ConstructBuilding(FString BuildingName);
UPROPERTY(EditAnywhere, BluePrintReadOnly, Category = "BuildingClasses")
TSubclassOf<class BuildingClass> SmallHouseClass;
Thanks for answers all.
Problem solved by :
Moving
PlayerControllerPtr = Cast<AMyPlayerController>(this->GetOwningPlayer());
from widget's constructor to widget's BeginPlay() event.