Stabilize investor visual smoke build

This commit is contained in:
2026-05-19 22:28:35 -07:00
parent d2b8185333
commit 4e17cede2d
19 changed files with 149 additions and 135 deletions
+1 -1
View File
@@ -829,7 +829,7 @@ Target deliverable: A small group can join a server, spawn into one biome, gathe
- [ ] Define default, recommended, and cinematic investor rendering presets, with ray tracing available only as an optional high-end/cinematic mode and never required for baseline visual credibility. - [ ] Define default, recommended, and cinematic investor rendering presets, with ray tracing available only as an optional high-end/cinematic mode and never required for baseline visual credibility.
- [ ] Verify the non-ray-traced compatibility/default path still looks credible on common investor, tester, and remote-session hardware. - [ ] Verify the non-ray-traced compatibility/default path still looks credible on common investor, tester, and remote-session hardware.
- [ ] Add packaged-demo visual QA screenshots or short clips for startup credits, character selection, first spawn, terrain, vegetation, water, campfire, shelter, pause menu, and save/quit before each investor build is called ready. - [ ] Add packaged-demo visual QA screenshots or short clips for startup credits, character selection, first spawn, terrain, vegetation, water, campfire, shelter, pause menu, and save/quit before each investor build is called ready.
- [ ] Add an investor-demo acceptance gate: no current build should be described as investor visual MVP if menus are confusing, character art is mannequin-only, terrain is flat/tan, foliage is absent or unreadable, or core objects still read as primitive debug shapes. - [x] Add an investor-demo acceptance gate: no current build should be described as investor visual MVP if menus are confusing, character art is mannequin-only, terrain is flat/tan, foliage is absent or unreadable, or core objects still read as primitive debug shapes.
## 0.1.P MVP Audio And Atmosphere ## 0.1.P MVP Audio And Atmosphere
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+8
View File
@@ -0,0 +1,8 @@
@echo off
setlocal
set "PACKAGE_DIR=%~dp0..\Builds\WindowsDevelopment"
set "GAME_EXE=%PACKAGE_DIR%\AgrarianGame\Binaries\Win64\AgrarianGame.exe"
cd /d "%PACKAGE_DIR%"
"%GAME_EXE%" -windowed -ResX=1280 -ResY=720 -ExecCmds=AgrarianInvestorSmokeTest -nosound
+35 -12
View File
@@ -30,9 +30,9 @@ PLACEHOLDER_MESHES = {
for name in PLACEHOLDER_MESH_SOURCES for name in PLACEHOLDER_MESH_SOURCES
} }
FOLIAGE_MESHES = { FOLIAGE_MESHES = {
"tree": PLACEHOLDER_MESHES["SM_AGR_Placeholder_Cylinder"], "tree": "/Engine/BasicShapes/Cone",
"shrub": PLACEHOLDER_MESHES["SM_AGR_Placeholder_Cube"], "shrub": "/Engine/BasicShapes/Sphere",
"grass": PLACEHOLDER_MESHES["SM_AGR_Placeholder_Cylinder"], "grass": "/Engine/BasicShapes/Plane",
} }
VARIATION_MESHES = { VARIATION_MESHES = {
"cube": PLACEHOLDER_MESHES["SM_AGR_Placeholder_Cube"], "cube": PLACEHOLDER_MESHES["SM_AGR_Placeholder_Cube"],
@@ -40,29 +40,31 @@ VARIATION_MESHES = {
"cylinder": PLACEHOLDER_MESHES["SM_AGR_Placeholder_Cylinder"], "cylinder": PLACEHOLDER_MESHES["SM_AGR_Placeholder_Cylinder"],
"quarter_cylinder": PLACEHOLDER_MESHES["SM_AGR_Placeholder_QuarterCylinder"], "quarter_cylinder": PLACEHOLDER_MESHES["SM_AGR_Placeholder_QuarterCylinder"],
"plane": PLACEHOLDER_MESHES["SM_AGR_Placeholder_Plane"], "plane": PLACEHOLDER_MESHES["SM_AGR_Placeholder_Plane"],
"sphere": "/Engine/BasicShapes/Sphere",
"cone": "/Engine/BasicShapes/Cone",
} }
MATERIAL_FOLDER = "/Game/Agrarian/Materials" MATERIAL_FOLDER = "/Game/Agrarian/Materials"
ENVIRONMENT_MATERIALS = { ENVIRONMENT_MATERIALS = {
"terrain": { "terrain": {
"path": f"{MATERIAL_FOLDER}/M_AGR_GZ_Terrain_CoastalScrub", "path": f"{MATERIAL_FOLDER}/M_AGR_GZ_Terrain_CoastalScrub",
"color": unreal.LinearColor(0.28, 0.24, 0.16, 1.0), "color": unreal.LinearColor(0.16, 0.23, 0.12, 1.0),
"roughness": 0.92, "roughness": 0.92,
}, },
"tree": { "tree": {
"path": f"{MATERIAL_FOLDER}/M_AGR_GZ_Tree_CoastalOak", "path": f"{MATERIAL_FOLDER}/M_AGR_GZ_Tree_CoastalOak",
"color": unreal.LinearColor(0.18, 0.31, 0.16, 1.0), "color": unreal.LinearColor(0.07, 0.18, 0.06, 1.0),
"roughness": 0.88, "roughness": 0.88,
"used_with_instanced_static_meshes": True, "used_with_instanced_static_meshes": True,
}, },
"shrub": { "shrub": {
"path": f"{MATERIAL_FOLDER}/M_AGR_GZ_Shrub_CoyoteBrush", "path": f"{MATERIAL_FOLDER}/M_AGR_GZ_Shrub_CoyoteBrush",
"color": unreal.LinearColor(0.31, 0.39, 0.20, 1.0), "color": unreal.LinearColor(0.15, 0.28, 0.10, 1.0),
"roughness": 0.9, "roughness": 0.9,
"used_with_instanced_static_meshes": True, "used_with_instanced_static_meshes": True,
}, },
"grass": { "grass": {
"path": f"{MATERIAL_FOLDER}/M_AGR_GZ_Grass_DryCoastal", "path": f"{MATERIAL_FOLDER}/M_AGR_GZ_Grass_DryCoastal",
"color": unreal.LinearColor(0.47, 0.42, 0.23, 1.0), "color": unreal.LinearColor(0.32, 0.34, 0.13, 1.0),
"roughness": 0.95, "roughness": 0.95,
"used_with_instanced_static_meshes": True, "used_with_instanced_static_meshes": True,
}, },
@@ -88,7 +90,7 @@ ENVIRONMENT_MATERIALS = {
}, },
"fresh_water": { "fresh_water": {
"path": f"{MATERIAL_FOLDER}/M_AGR_GZ_FreshWater", "path": f"{MATERIAL_FOLDER}/M_AGR_GZ_FreshWater",
"color": unreal.LinearColor(0.08, 0.28, 0.38, 1.0), "color": unreal.LinearColor(0.02, 0.16, 0.30, 1.0),
"roughness": 0.35, "roughness": 0.35,
}, },
} }
@@ -349,7 +351,7 @@ WEATHER_EXPOSURE_ZONES = [
ENVIRONMENT_VARIATION_ACTORS = [ ENVIRONMENT_VARIATION_ACTORS = [
{ {
"label": "AGR_GZ_EnvVar_Tree_Canopy_01", "label": "AGR_GZ_EnvVar_Tree_Canopy_01",
"mesh_key": "chamfer_cube", "mesh_key": "sphere",
"material_key": "tree", "material_key": "tree",
"location_xy": unreal.Vector(-27500.0, 6900.0, 0.0), "location_xy": unreal.Vector(-27500.0, 6900.0, 0.0),
"z_offset": 390.0, "z_offset": 390.0,
@@ -367,7 +369,7 @@ ENVIRONMENT_VARIATION_ACTORS = [
}, },
{ {
"label": "AGR_GZ_EnvVar_Tree_Canopy_02", "label": "AGR_GZ_EnvVar_Tree_Canopy_02",
"mesh_key": "chamfer_cube", "mesh_key": "sphere",
"material_key": "tree", "material_key": "tree",
"location_xy": unreal.Vector(17600.0, 31800.0, 0.0), "location_xy": unreal.Vector(17600.0, 31800.0, 0.0),
"z_offset": 430.0, "z_offset": 430.0,
@@ -385,7 +387,7 @@ ENVIRONMENT_VARIATION_ACTORS = [
}, },
{ {
"label": "AGR_GZ_EnvVar_Bush_Rounded_01", "label": "AGR_GZ_EnvVar_Bush_Rounded_01",
"mesh_key": "chamfer_cube", "mesh_key": "sphere",
"material_key": "shrub", "material_key": "shrub",
"location_xy": unreal.Vector(-33400.0, -15200.0, 0.0), "location_xy": unreal.Vector(-33400.0, -15200.0, 0.0),
"z_offset": 70.0, "z_offset": 70.0,
@@ -394,7 +396,7 @@ ENVIRONMENT_VARIATION_ACTORS = [
}, },
{ {
"label": "AGR_GZ_EnvVar_Bush_Rounded_02", "label": "AGR_GZ_EnvVar_Bush_Rounded_02",
"mesh_key": "chamfer_cube", "mesh_key": "sphere",
"material_key": "shrub", "material_key": "shrub",
"location_xy": unreal.Vector(30400.0, -3900.0, 0.0), "location_xy": unreal.Vector(30400.0, -3900.0, 0.0),
"z_offset": 75.0, "z_offset": 75.0,
@@ -810,6 +812,27 @@ def ensure_environment_materials():
unreal.MaterialEditingLibrary.recompile_material(material) unreal.MaterialEditingLibrary.recompile_material(material)
unreal.EditorAssetLibrary.save_asset(spec["path"]) unreal.EditorAssetLibrary.save_asset(spec["path"])
unreal.log(f"Created Ground Zero environment material: {spec['path']}") unreal.log(f"Created Ground Zero environment material: {spec['path']}")
else:
base_color = unreal.MaterialEditingLibrary.get_material_property_input_node(
material, unreal.MaterialProperty.MP_BASE_COLOR
)
if base_color and hasattr(base_color, "set_editor_property"):
try:
base_color.set_editor_property("constant", spec["color"])
except Exception:
pass
roughness = unreal.MaterialEditingLibrary.get_material_property_input_node(
material, unreal.MaterialProperty.MP_ROUGHNESS
)
if roughness and hasattr(roughness, "set_editor_property"):
try:
roughness.set_editor_property("r", spec["roughness"])
except Exception:
pass
unreal.MaterialEditingLibrary.recompile_material(material)
unreal.EditorAssetLibrary.save_asset(spec["path"], only_if_is_dirty=False)
if spec.get("used_with_instanced_static_meshes"): if spec.get("used_with_instanced_static_meshes"):
material.set_editor_property("used_with_instanced_static_meshes", True) material.set_editor_property("used_with_instanced_static_meshes", True)
unreal.MaterialEditingLibrary.recompile_material(material) unreal.MaterialEditingLibrary.recompile_material(material)
+3 -3
View File
@@ -4,9 +4,9 @@ import unreal
MAP_PATH = "/Game/Agrarian/Maps/L_GroundZeroTerrain_Test" MAP_PATH = "/Game/Agrarian/Maps/L_GroundZeroTerrain_Test"
FOLIAGE_LABEL = "AGR_GroundZeroFoliage_FirstPass" FOLIAGE_LABEL = "AGR_GroundZeroFoliage_FirstPass"
EXPECTED_COUNTS = { EXPECTED_COUNTS = {
"trees": 42, "trees": 96,
"shrubs": 96, "shrubs": 220,
"grass": 180, "grass": 420,
} }
@@ -14,11 +14,9 @@
#include "AgrarianSurvivalComponent.h" #include "AgrarianSurvivalComponent.h"
#include "Camera/CameraActor.h" #include "Camera/CameraActor.h"
#include "Components/SkeletalMeshComponent.h" #include "Components/SkeletalMeshComponent.h"
#include "Components/StaticMeshComponent.h"
#include "EnhancedInputSubsystems.h" #include "EnhancedInputSubsystems.h"
#include "Engine/LocalPlayer.h" #include "Engine/LocalPlayer.h"
#include "Engine/SkeletalMesh.h" #include "Engine/SkeletalMesh.h"
#include "Engine/StaticMesh.h"
#include "GameFramework/Character.h" #include "GameFramework/Character.h"
#include "GameFramework/CharacterMovementComponent.h" #include "GameFramework/CharacterMovementComponent.h"
#include "InputCoreTypes.h" #include "InputCoreTypes.h"
@@ -96,57 +94,6 @@ namespace
: TEXT("/Game/Agrarian/Characters/Materials/M_AGR_CharacterProxy_Workwear_Male.M_AGR_CharacterProxy_Workwear_Male"); : TEXT("/Game/Agrarian/Characters/Materials/M_AGR_CharacterProxy_Workwear_Male.M_AGR_CharacterProxy_Workwear_Male");
} }
UStaticMeshComponent* EnsureMvpPresentationComponent(
AAgrarianGameCharacter* Character,
const FName ComponentName,
UStaticMesh* Mesh,
UMaterialInterface* Material,
const FVector& RelativeLocation,
const FRotator& RelativeRotation,
const FVector& RelativeScale)
{
if (!Character || !Mesh)
{
return nullptr;
}
UStaticMeshComponent* Component = nullptr;
TArray<UStaticMeshComponent*> ExistingComponents;
Character->GetComponents<UStaticMeshComponent>(ExistingComponents);
for (UStaticMeshComponent* ExistingComponent : ExistingComponents)
{
if (ExistingComponent && ExistingComponent->GetFName() == ComponentName)
{
Component = ExistingComponent;
break;
}
}
if (!Component)
{
Component = NewObject<UStaticMeshComponent>(Character, ComponentName);
if (!Component)
{
return nullptr;
}
Component->SetupAttachment(Character->GetRootComponent());
Component->RegisterComponent();
Character->AddInstanceComponent(Component);
}
Component->SetStaticMesh(Mesh);
if (Material)
{
Component->SetMaterial(0, Material);
}
Component->SetCollisionEnabled(ECollisionEnabled::NoCollision);
Component->SetGenerateOverlapEvents(false);
Component->SetRelativeLocation(RelativeLocation);
Component->SetRelativeRotation(RelativeRotation);
Component->SetRelativeScale3D(RelativeScale);
Component->SetHiddenInGame(false);
return Component;
}
} }
void AAgrarianGamePlayerController::BeginPlay() void AAgrarianGamePlayerController::BeginPlay()
@@ -496,60 +443,7 @@ void AAgrarianGamePlayerController::ApplyMvpCharacterProxyToPawn()
} }
} }
UStaticMesh* ChamferMesh = LoadObject<UStaticMesh>( // Blockout clothing and pack geometry was removed because it read as broken placeholder art in the investor build.
nullptr,
TEXT("/Game/Agrarian/Environment/PlaceholderMeshes/SM_AGR_Placeholder_ChamferCube.SM_AGR_Placeholder_ChamferCube"));
UStaticMesh* CubeMesh = LoadObject<UStaticMesh>(
nullptr,
TEXT("/Game/Agrarian/Environment/PlaceholderMeshes/SM_AGR_Placeholder_Cube.SM_AGR_Placeholder_Cube"));
UStaticMesh* CylinderMesh = LoadObject<UStaticMesh>(
nullptr,
TEXT("/Game/Agrarian/Environment/PlaceholderMeshes/SM_AGR_Placeholder_Cylinder.SM_AGR_Placeholder_Cylinder"));
UMaterialInterface* WorkwearMaterial = LoadObject<UMaterialInterface>(nullptr, GetMvpCharacterProxyMaterialPath(SelectedMvpCharacterProxyId));
UMaterialInterface* PackMaterial = LoadObject<UMaterialInterface>(
nullptr,
TEXT("/Game/Agrarian/Materials/M_AGR_GZ_Fiber_Resource.M_AGR_GZ_Fiber_Resource"));
UMaterialInterface* BootMaterial = LoadObject<UMaterialInterface>(
nullptr,
TEXT("/Game/Agrarian/Materials/M_AGR_GZ_Wood_Resource.M_AGR_GZ_Wood_Resource"));
const bool bFemaleProxy = SelectedMvpCharacterProxyId == TEXT("female");
const float TorsoWidth = bFemaleProxy ? 0.33f : 0.38f;
const float TorsoDepth = bFemaleProxy ? 0.18f : 0.22f;
const float PackWidth = bFemaleProxy ? 0.24f : 0.28f;
EnsureMvpPresentationComponent(
AgrarianCharacter,
TEXT("MvpWorkwearTorsoProxy"),
ChamferMesh,
WorkwearMaterial,
FVector(2.0f, 0.0f, 102.0f),
FRotator(0.0f, 0.0f, 0.0f),
FVector(TorsoWidth, TorsoDepth, 0.62f));
EnsureMvpPresentationComponent(
AgrarianCharacter,
TEXT("MvpWorkwearBackpackProxy"),
ChamferMesh,
PackMaterial,
FVector(-24.0f, 0.0f, 106.0f),
FRotator(0.0f, 0.0f, 0.0f),
FVector(PackWidth, 0.16f, 0.48f));
EnsureMvpPresentationComponent(
AgrarianCharacter,
TEXT("MvpWorkwearBedrollProxy"),
CylinderMesh,
PackMaterial,
FVector(-30.0f, 0.0f, 134.0f),
FRotator(0.0f, 90.0f, 0.0f),
FVector(0.12f, 0.12f, 0.58f));
EnsureMvpPresentationComponent(
AgrarianCharacter,
TEXT("MvpWorkwearBootsProxy"),
ChamferMesh,
BootMaterial,
FVector(0.0f, 0.0f, 26.0f),
FRotator(0.0f, 0.0f, 0.0f),
FVector(0.34f, 0.20f, 0.18f));
} }
void AAgrarianGamePlayerController::AgrarianGrantItem(FName ItemId, int32 Quantity) void AAgrarianGamePlayerController::AgrarianGrantItem(FName ItemId, int32 Quantity)
@@ -817,6 +711,11 @@ void AAgrarianGamePlayerController::AgrarianCompleteFrontend()
SetMvpFrontendPresentationActive(false); SetMvpFrontendPresentationActive(false);
SetInputMode(FInputModeGameOnly()); SetInputMode(FInputModeGameOnly());
bShowMouseCursor = false; bShowMouseCursor = false;
if (const APawn* ControlledPawn = GetPawn())
{
SetControlRotation(FRotator(-8.0f, ControlledPawn->GetActorRotation().Yaw, 0.0f));
}
} }
void AAgrarianGamePlayerController::AgrarianShowMvpScreen(FName ScreenName) void AAgrarianGamePlayerController::AgrarianShowMvpScreen(FName ScreenName)
@@ -865,6 +764,78 @@ void AAgrarianGamePlayerController::AgrarianShowMvpScreen(FName ScreenName)
ClientMessage(TEXT("Usage: AgrarianShowMvpScreen main|character|join|loading|saving")); ClientMessage(TEXT("Usage: AgrarianShowMvpScreen main|character|join|loading|saving"));
} }
void AAgrarianGamePlayerController::AgrarianInvestorSmokeTest(float CaptureDelaySeconds, float QuitDelaySeconds)
{
if (!IsLocalPlayerController())
{
return;
}
const float ClampedCaptureDelaySeconds = FMath::Max(2.0f, CaptureDelaySeconds);
const float ClampedQuitDelaySeconds = FMath::Max(ClampedCaptureDelaySeconds + 4.0f, QuitDelaySeconds);
FTimerDelegate EnterWorldDelegate;
EnterWorldDelegate.BindWeakLambda(this, [this]()
{
if (!MvpFrontendWidget)
{
ShowMvpFrontend();
}
SelectedMvpCharacterProxyId = TEXT("female");
if (MvpFrontendWidget)
{
MvpFrontendWidget->SetSelectedCharacterArchetype(EAgrarianMvpCharacterArchetype::YoungAdultFemale);
}
AgrarianCompleteFrontend();
if (AAgrarianDebugHUD* AgrarianHUD = GetHUD<AAgrarianDebugHUD>())
{
AgrarianHUD->bShowDebugHUD = false;
AgrarianHUD->bShowCriticalStatsHUD = false;
AgrarianHUD->bShowInventoryHUD = false;
AgrarianHUD->bShowCraftingHUD = false;
}
if (APawn* ControlledPawn = GetPawn())
{
const FRotator InvestorViewRotation(-4.0f, 42.0f, 0.0f);
ControlledPawn->SetActorRotation(FRotator(0.0f, InvestorViewRotation.Yaw, 0.0f));
SetControlRotation(InvestorViewRotation);
}
ClientMessage(TEXT("Investor smoke test entered Ground Zero as the female MVP character proxy."));
});
FTimerHandle EnterWorldTimerHandle;
GetWorldTimerManager().SetTimer(EnterWorldTimerHandle, EnterWorldDelegate, 0.75f, false);
FTimerDelegate ScreenshotDelegate;
ScreenshotDelegate.BindWeakLambda(this, [this]()
{
ClientMessage(TEXT("Investor smoke test capturing gameplay screenshot."));
ConsoleCommand(TEXT("HighResShot 1"));
});
FTimerHandle ScreenshotTimerHandle;
GetWorldTimerManager().SetTimer(ScreenshotTimerHandle, ScreenshotDelegate, ClampedCaptureDelaySeconds, false);
FTimerDelegate QuitDelegate;
QuitDelegate.BindWeakLambda(this, [this]()
{
ClientMessage(TEXT("Investor smoke test completed; quitting packaged client."));
ConsoleCommand(TEXT("quit"));
});
FTimerHandle QuitTimerHandle;
GetWorldTimerManager().SetTimer(QuitTimerHandle, QuitDelegate, ClampedQuitDelaySeconds, false);
ClientMessage(FString::Printf(
TEXT("Investor smoke test scheduled: screenshot in %.1fs, quit in %.1fs."),
ClampedCaptureDelaySeconds,
ClampedQuitDelaySeconds));
}
void AAgrarianGamePlayerController::AgrarianTravel(float X, float Y, float Z) void AAgrarianGamePlayerController::AgrarianTravel(float X, float Y, float Z)
{ {
ServerAgrarianTravel(FVector(X, Y, Z)); ServerAgrarianTravel(FVector(X, Y, Z));
@@ -153,6 +153,9 @@ public:
UFUNCTION(Exec) UFUNCTION(Exec)
void AgrarianShowMvpScreen(FName ScreenName); void AgrarianShowMvpScreen(FName ScreenName);
UFUNCTION(Exec)
void AgrarianInvestorSmokeTest(float CaptureDelaySeconds = 6.0f, float QuitDelaySeconds = 18.0f);
UFUNCTION(Exec) UFUNCTION(Exec)
void AgrarianTravel(float X, float Y, float Z); void AgrarianTravel(float X, float Y, float Z);
@@ -15,7 +15,7 @@ AAgrarianMapBoundaryVolume::AAgrarianMapBoundaryVolume()
RootComponent = BoundaryVolume; RootComponent = BoundaryVolume;
BoundaryVolume->SetBoxExtent(FVector(50000.0f, 50000.0f, 25000.0f)); BoundaryVolume->SetBoxExtent(FVector(50000.0f, 50000.0f, 25000.0f));
BoundaryVolume->SetCollisionEnabled(ECollisionEnabled::NoCollision); BoundaryVolume->SetCollisionEnabled(ECollisionEnabled::NoCollision);
BoundaryVolume->SetHiddenInGame(false); BoundaryVolume->SetHiddenInGame(true);
BoundaryVolume->ShapeColor = FColor::Yellow; BoundaryVolume->ShapeColor = FColor::Yellow;
} }
@@ -7,6 +7,7 @@
#include "Components/DirectionalLightComponent.h" #include "Components/DirectionalLightComponent.h"
#include "Components/ExponentialHeightFogComponent.h" #include "Components/ExponentialHeightFogComponent.h"
#include "Components/SceneComponent.h" #include "Components/SceneComponent.h"
#include "Components/SkyAtmosphereComponent.h"
#include "Components/SkyLightComponent.h" #include "Components/SkyLightComponent.h"
#include "Engine/World.h" #include "Engine/World.h"
#include "ProfilingDebugging/CpuProfilerTrace.h" #include "ProfilingDebugging/CpuProfilerTrace.h"
@@ -30,6 +31,10 @@ AAgrarianSkyLightingController::AAgrarianSkyLightingController()
SkyLight->SetIntensity(ClearSkyLightIntensity); SkyLight->SetIntensity(ClearSkyLightIntensity);
SkyLight->SetMobility(EComponentMobility::Movable); SkyLight->SetMobility(EComponentMobility::Movable);
SkyAtmosphere = CreateDefaultSubobject<USkyAtmosphereComponent>(TEXT("SkyAtmosphere"));
SkyAtmosphere->SetupAttachment(SceneRoot);
SkyAtmosphere->SetMobility(EComponentMobility::Movable);
HeightFog = CreateDefaultSubobject<UExponentialHeightFogComponent>(TEXT("HeightFog")); HeightFog = CreateDefaultSubobject<UExponentialHeightFogComponent>(TEXT("HeightFog"));
HeightFog->SetupAttachment(SceneRoot); HeightFog->SetupAttachment(SceneRoot);
HeightFog->SetFogDensity(ClearFogDensity); HeightFog->SetFogDensity(ClearFogDensity);
@@ -10,6 +10,7 @@
class UDirectionalLightComponent; class UDirectionalLightComponent;
class UExponentialHeightFogComponent; class UExponentialHeightFogComponent;
class USceneComponent; class USceneComponent;
class USkyAtmosphereComponent;
class USkyLightComponent; class USkyLightComponent;
UCLASS(Blueprintable) UCLASS(Blueprintable)
@@ -32,6 +33,9 @@ public:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Agrarian|Sky") UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Agrarian|Sky")
TObjectPtr<USkyLightComponent> SkyLight; TObjectPtr<USkyLightComponent> SkyLight;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Agrarian|Sky")
TObjectPtr<USkyAtmosphereComponent> SkyAtmosphere;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Agrarian|Sky") UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Agrarian|Sky")
TObjectPtr<UExponentialHeightFogComponent> HeightFog; TObjectPtr<UExponentialHeightFogComponent> HeightFog;