Untitled
unknown
c_cpp
10 months ago
10 kB
14
Indexable
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "WindowSystem/WindowSystemDemoActor.generated.h"
class UWindowManagerComponent;
class UWindowWidget;
/**
* Debug-friendly demo actor:
* - Retries until PlayerController/Desktop exist
* - Logs every step + shows on-screen messages
* - Spawns UMG & 3D Viewport windows (with WindowIds for persistence)
*/
UCLASS()
class VIEWPORTWINDOWS_API AWindowSystemDemoActor : public AActor
{
GENERATED_BODY()
public:
AWindowSystemDemoActor();
protected:
virtual void BeginPlay() override;
/** Creates the demo windows (self-retries until Desktop is valid) */
void SpawnDemoWindows();
/** Debug helpers */
void LogMsg(const FString& Msg, FColor Color = FColor::Cyan) const;
void DumpState(const TCHAR* Phase) const;
/** Retry timer */
FTimerHandle SpawnRetryHandle;
int32 SpawnRetryCount = 0;
/** Track spawned windows so we don't duplicate them */
UPROPERTY()
UWindowWidget* SpawnedUMG = nullptr;
UPROPERTY()
UWindowWidget* SpawnedViewport = nullptr;
public: // Components
/** Window manager component that builds the Desktop and spawns windows */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Viewport Windows")
UWindowManagerComponent* WindowManager;
public: // Configurable demo settings
/** Spawn demo windows on BeginPlay */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Viewport Windows|Demo")
bool bOpenOnBeginPlay = true;
/** Class for the UMG content window (leave None to use SimpleLabelWidget) */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Viewport Windows|Demo")
TSubclassOf<UUserWidget> DemoContentClass;
/** Optional tag to pick a LookAt actor for the 3D viewport window */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Viewport Windows|Demo")
FName LookAtTag = TEXT("DemoCamTarget");
/** ---- UMG Window params ---- */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Viewport Windows|Demo")
FText UMGWindowTitle = FText::FromString(TEXT("UMG Window"));
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Viewport Windows|Demo")
FVector2D UMGWindowPosition = FVector2D(80.f, 80.f);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Viewport Windows|Demo")
FVector2D UMGWindowSize = FVector2D(420.f, 280.f);
/** Stable ID for persistence (pin to save/lock) */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Viewport Windows|Demo")
FName UMGWindowId = TEXT("UMG_Main");
/** ---- 3D Viewport Window params ---- */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Viewport Windows|Demo")
FText ViewportWindowTitle = FText::FromString(TEXT("3D Viewport"));
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Viewport Windows|Demo")
FVector2D ViewportWindowPosition = FVector2D(540.f, 120.f);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Viewport Windows|Demo")
FVector2D ViewportWindowSize = FVector2D(600.f, 380.f);
/** Stable ID for persistence (pin to save/lock) */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Viewport Windows|Demo")
FName ViewportWindowId = TEXT("Viewport_Main");
};
#include "WindowSystem/WindowSystemDemoActor.h"
#include "WindowSystem/WindowManagerComponent.h"
#include "WindowSystem/WindowWidget.h"
#include "WindowSystem/SimpleLabelWidget.h"
#include "Components/CanvasPanelSlot.h"
#include "Kismet/GameplayStatics.h"
#include "GameFramework/PlayerController.h"
#include "Engine/Engine.h"
#include "TimerManager.h"
DEFINE_LOG_CATEGORY_STATIC(LogViewportWindowsDemo, Log, All);
AWindowSystemDemoActor::AWindowSystemDemoActor()
{
PrimaryActorTick.bCanEverTick = false;
WindowManager = CreateDefaultSubobject<UWindowManagerComponent>(TEXT("WindowManager"));
}
void AWindowSystemDemoActor::LogMsg(const FString& Msg, FColor Color) const
{
UE_LOG(LogViewportWindowsDemo, Log, TEXT("%s"), *Msg);
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 4.0f, Color, Msg);
}
}
void AWindowSystemDemoActor::DumpState(const TCHAR* Phase) const
{
UWorld* World = GetWorld();
APlayerController* PC = World ? UGameplayStatics::GetPlayerController(World, 0) : nullptr;
const bool bPCReady = (PC && PC->IsLocalController());
const void* DesktopPtr = WindowManager ? WindowManager->GetDesktop() : nullptr;
FString Msg = FString::Printf(
TEXT("[VPW Demo] %s\n World=%s PC=%s Local=%s WindowManager=%s Desktop=%s\n DemoContentClass=%s UMGId=%s VPId=%s"),
Phase,
*GetNameSafe(World),
*GetNameSafe(PC),
bPCReady ? TEXT("Yes") : TEXT("No"),
*GetNameSafe(WindowManager),
DesktopPtr ? TEXT("Valid") : TEXT("NULL"),
*GetNameSafe(DemoContentClass),
*UMGWindowId.ToString(),
*ViewportWindowId.ToString()
);
LogMsg(Msg, FColor::Silver);
}
void AWindowSystemDemoActor::BeginPlay()
{
Super::BeginPlay();
DumpState(TEXT("BeginPlay"));
if (!bOpenOnBeginPlay)
{
LogMsg(TEXT("[VPW Demo] bOpenOnBeginPlay = false (skipping window spawn)"), FColor::Yellow);
return;
}
if (!WindowManager)
{
LogMsg(TEXT("[VPW Demo] WindowManager component is NULL!"), FColor::Red);
return;
}
// Kick desktop initialization (it will succeed once PC is valid)
WindowManager->InitializeDesktop();
LogMsg(TEXT("[VPW Demo] Called WindowManager->InitializeDesktop()"), FColor::Cyan);
// Try to spawn now; will self-retry until Desktop is valid.
SpawnRetryCount = 0;
SpawnDemoWindows();
}
void AWindowSystemDemoActor::SpawnDemoWindows()
{
UWorld* World = GetWorld();
if (!World)
{
LogMsg(TEXT("[VPW Demo] World is NULL in SpawnDemoWindows"), FColor::Red);
return;
}
// Ensure Desktop exists first
if (!WindowManager || !WindowManager->GetDesktop())
{
if (++SpawnRetryCount <= 40) // ~2 seconds total @ 0.05s
{
LogMsg(FString::Printf(TEXT("[VPW Demo] Desktop not ready (try %d) — retrying..."), SpawnRetryCount), FColor::Yellow);
World->GetTimerManager().SetTimer(SpawnRetryHandle, this, &AWindowSystemDemoActor::SpawnDemoWindows, 0.05f, false);
}
else
{
LogMsg(TEXT("[VPW Demo] Desktop never became ready — aborting demo spawn."), FColor::Red);
DumpState(TEXT("DesktopFailed"));
}
return;
}
DumpState(TEXT("DesktopReady"));
// -------- UMG Window --------
if (!SpawnedUMG)
{
TSubclassOf<UUserWidget> ContentClass = DemoContentClass;
if (!ContentClass)
{
LogMsg(TEXT("[VPW Demo] DemoContentClass is None — using USimpleLabelWidget fallback."), FColor::Yellow);
ContentClass = USimpleLabelWidget::StaticClass();
}
LogMsg(FString::Printf(TEXT("[VPW Demo] Spawning UMG Window: Pos=(%.1f,%.1f) Size=(%.1f,%.1f) Title='%s' Id='%s'"),
UMGWindowPosition.X, UMGWindowPosition.Y, UMGWindowSize.X, UMGWindowSize.Y,
*UMGWindowTitle.ToString(), *UMGWindowId.ToString()), FColor::Green);
SpawnedUMG = WindowManager->CreateUMGWindow(
ContentClass,
UMGWindowPosition,
UMGWindowSize,
UMGWindowTitle,
UMGWindowId
);
if (SpawnedUMG)
{
if (UCanvasPanelSlot* C = SpawnedUMG->GetCanvasSlot())
{
LogMsg(FString::Printf(TEXT("[VPW Demo] UMG Window CREATED. Canvas Pos=(%.1f,%.1f) Size=(%.1f,%.1f) Z=%d"),
C->GetPosition().X, C->GetPosition().Y, C->GetSize().X, C->GetSize().Y, C->GetZOrder()), FColor::Green);
}
else
{
LogMsg(TEXT("[VPW Demo] UMG Window CREATED but CanvasSlot is NULL."), FColor::Yellow);
}
}
else
{
LogMsg(TEXT("[VPW Demo] FAILED to create UMG Window."), FColor::Red);
}
}
// -------- 3D Viewport Window --------
if (!SpawnedViewport)
{
AActor* LookAt = nullptr;
if (!LookAtTag.IsNone())
{
TArray<AActor*> Found;
UGameplayStatics::GetAllActorsWithTag(World, LookAtTag, Found);
if (Found.Num() > 0)
{
LookAt = Found[0];
LogMsg(FString::Printf(TEXT("[VPW Demo] LookAt actor found by tag '%s': %s"),
*LookAtTag.ToString(), *GetNameSafe(LookAt)), FColor::Cyan);
}
else
{
LogMsg(FString::Printf(TEXT("[VPW Demo] No actor found with tag '%s' (this is OK)."), *LookAtTag.ToString()), FColor::Yellow);
}
}
LogMsg(FString::Printf(TEXT("[VPW Demo] Spawning Viewport Window: Pos=(%.1f,%.1f) Size=(%.1f,%.1f) Title='%s' Id='%s'"),
ViewportWindowPosition.X, ViewportWindowPosition.Y, ViewportWindowSize.X, ViewportWindowSize.Y,
*ViewportWindowTitle.ToString(), *ViewportWindowId.ToString()), FColor::Green);
SpawnedViewport = WindowManager->Create3DViewportWindow(
LookAt,
ViewportWindowPosition,
ViewportWindowSize,
ViewportWindowTitle,
ViewportWindowId
);
if (SpawnedViewport)
{
if (UCanvasPanelSlot* C = SpawnedViewport->GetCanvasSlot())
{
LogMsg(FString::Printf(TEXT("[VPW Demo] Viewport Window CREATED. Canvas Pos=(%.1f,%.1f) Size=(%.1f,%.1f) Z=%d"),
C->GetPosition().X, C->GetPosition().Y, C->GetSize().X, C->GetSize().Y, C->GetZOrder()), FColor::Green);
}
else
{
LogMsg(TEXT("[VPW Demo] Viewport Window CREATED but CanvasSlot is NULL."), FColor::Yellow);
}
}
else
{
LogMsg(TEXT("[VPW Demo] FAILED to create Viewport Window."), FColor::Red);
}
}
// Final state
if (SpawnedUMG || SpawnedViewport)
{
DumpState(TEXT("SpawnComplete"));
}
}
Editor is loading...
Leave a Comment