Add first pass sky lighting
This commit is contained in:
@@ -435,7 +435,7 @@ Target deliverable: A small group can join a server, spawn into one biome, gathe
|
|||||||
- [x] Add weather save/load support. Added `LoadCurrentWorld` as the unified persistence load path, restored weather/time before players and world actors, updated the admin load command to use the combined path, and extended the persistence smoke test to prove provider-backed weather metadata survives save/load.
|
- [x] Add weather save/load support. Added `LoadCurrentWorld` as the unified persistence load path, restored weather/time before players and world actors, updated the admin load command to use the combined path, and extended the persistence smoke test to prove provider-backed weather metadata survives save/load.
|
||||||
- [x] Connect weather to body temperature.
|
- [x] Connect weather to body temperature.
|
||||||
- [x] Connect shelter to weather protection. Survival now calculates the best overlapping shelter protection volume, replicates current weather protection, reduces ambient exposure and cold damage by shelter coverage, trends care-history shelter quality toward active protection, and shows shelter protection on the dev HUD.
|
- [x] Connect shelter to weather protection. Survival now calculates the best overlapping shelter protection volume, replicates current weather protection, reduces ambient exposure and cold damage by shelter coverage, trends care-history shelter quality toward active protection, and shows shelter protection on the dev HUD.
|
||||||
- [ ] Add first-pass sky and lighting.
|
- [x] Add first-pass sky and lighting. Added `AAgrarianSkyLightingController` with movable sun, skylight, and fog components driven by replicated time, local sunrise/sunset, weather state, and provider cloud cover; updated the Ground Zero setup script to place the controller and remove legacy static lighting actors.
|
||||||
- [ ] Add audio cues for weather.
|
- [ ] Add audio cues for weather.
|
||||||
|
|
||||||
## 0.1.D Single Biome MVP Map
|
## 0.1.D Single Biome MVP Map
|
||||||
|
|||||||
Binary file not shown.
@@ -155,6 +155,15 @@ percentage, and trend the care-history shelter quality field toward the active
|
|||||||
protection level. The dev HUD shows current shelter protection so weather
|
protection level. The dev HUD shows current shelter protection so weather
|
||||||
pressure can be tuned during MVP tests.
|
pressure can be tuned during MVP tests.
|
||||||
|
|
||||||
|
First-pass sky and lighting use `AAgrarianSkyLightingController`. The controller
|
||||||
|
owns movable sun, skylight, and exponential-height-fog components and reads the
|
||||||
|
replicated `AAgrarianGameState` time, active tile sunrise/sunset, weather state,
|
||||||
|
and mapped cloud cover. It adjusts sun pitch, sun intensity/color, sky-light
|
||||||
|
intensity, and fog density every tick so the Ground Zero demo visually tracks
|
||||||
|
the represented local day/night cycle and current weather without hard-coded
|
||||||
|
static light settings. The Ground Zero map setup script places this controller
|
||||||
|
and removes the earlier static demo sun/skylight/fog actors.
|
||||||
|
|
||||||
The first real-weather adapter is `UAgrarianWeatherProviderSubsystem`. It uses
|
The first real-weather adapter is `UAgrarianWeatherProviderSubsystem`. It uses
|
||||||
Open-Meteo forecast requests keyed by tile center latitude/longitude, parses the
|
Open-Meteo forecast requests keyed by tile center latitude/longitude, parses the
|
||||||
current temperature, daily low/high, precipitation, wind, humidity, cloud cover,
|
current temperature, daily low/high, precipitation, wind, humidity, cloud cover,
|
||||||
|
|||||||
@@ -68,25 +68,11 @@ DEMO_ACTORS = [
|
|||||||
"rotation": unreal.Rotator(0.0, 135.0, 0.0),
|
"rotation": unreal.Rotator(0.0, 135.0, 0.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "AGR_DemoSun",
|
"label": "AGR_DemoSkyLightingController",
|
||||||
"class": unreal.DirectionalLight,
|
"class": unreal.AgrarianSkyLightingController,
|
||||||
"location_xy": unreal.Vector(-22000.0, -9000.0, 0.0),
|
|
||||||
"fixed_z": 35000.0,
|
|
||||||
"rotation": unreal.Rotator(-42.0, -35.0, 0.0),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "AGR_DemoSkyLight",
|
|
||||||
"class": unreal.SkyLight,
|
|
||||||
"location_xy": unreal.Vector(-18000.0, -7000.0, 0.0),
|
"location_xy": unreal.Vector(-18000.0, -7000.0, 0.0),
|
||||||
"fixed_z": 12000.0,
|
"fixed_z": 12000.0,
|
||||||
"rotation": unreal.Rotator(0.0, 0.0, 0.0),
|
"rotation": unreal.Rotator(-42.0, -35.0, 0.0),
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "AGR_DemoFog",
|
|
||||||
"class": unreal.ExponentialHeightFog,
|
|
||||||
"location_xy": unreal.Vector(-18000.0, -7000.0, 0.0),
|
|
||||||
"fixed_z": 4000.0,
|
|
||||||
"rotation": unreal.Rotator(0.0, 0.0, 0.0),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "AGR_DemoNoticeActor",
|
"label": "AGR_DemoNoticeActor",
|
||||||
@@ -97,6 +83,12 @@ DEMO_ACTORS = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
LEGACY_DEMO_LIGHTING_LABELS = {
|
||||||
|
"AGR_DemoSun",
|
||||||
|
"AGR_DemoSkyLight",
|
||||||
|
"AGR_DemoFog",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BIOME_RESOURCE_ACTORS = [
|
BIOME_RESOURCE_ACTORS = [
|
||||||
{
|
{
|
||||||
@@ -330,7 +322,7 @@ def spawn_foliage_actor(height_values):
|
|||||||
reserved_points = [
|
reserved_points = [
|
||||||
spec["location_xy"]
|
spec["location_xy"]
|
||||||
for spec in DEMO_ACTORS
|
for spec in DEMO_ACTORS
|
||||||
if spec["label"] not in {"AGR_DemoSun", "AGR_DemoSkyLight", "AGR_DemoFog", "AGR_DemoNoticeActor"}
|
if spec["label"] not in {"AGR_DemoSkyLightingController", "AGR_DemoNoticeActor"}
|
||||||
]
|
]
|
||||||
|
|
||||||
foliage_actor = unreal.AgrarianEditorAutomationLibrary.spawn_actor_in_editor_world(
|
foliage_actor = unreal.AgrarianEditorAutomationLibrary.spawn_actor_in_editor_world(
|
||||||
@@ -405,6 +397,7 @@ def main():
|
|||||||
raise RuntimeError(f"Could not load map: {MAP_PATH}")
|
raise RuntimeError(f"Could not load map: {MAP_PATH}")
|
||||||
|
|
||||||
labels = {spec["label"] for spec in DEMO_ACTORS}
|
labels = {spec["label"] for spec in DEMO_ACTORS}
|
||||||
|
labels.update(LEGACY_DEMO_LIGHTING_LABELS)
|
||||||
labels.update(spec["label"] for spec in BIOME_RESOURCE_ACTORS)
|
labels.update(spec["label"] for spec in BIOME_RESOURCE_ACTORS)
|
||||||
labels.update(spec["label"] for spec in WATER_SOURCE_ACTORS)
|
labels.update(spec["label"] for spec in WATER_SOURCE_ACTORS)
|
||||||
labels.add(FOLIAGE_LABEL)
|
labels.add(FOLIAGE_LABEL)
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
SKY_H = ROOT / "Source" / "AgrarianGame" / "AgrarianSkyLightingController.h"
|
||||||
|
SKY_CPP = ROOT / "Source" / "AgrarianGame" / "AgrarianSkyLightingController.cpp"
|
||||||
|
MAP_SETUP = ROOT / "Scripts" / "setup_ground_zero_demo_map.py"
|
||||||
|
TDD = ROOT / "Docs" / "TechnicalDesignDocument.md"
|
||||||
|
ROADMAP = ROOT / "AGRARIAN_DEVELOPMENT_ROADMAP.md"
|
||||||
|
|
||||||
|
|
||||||
|
EXPECTED = {
|
||||||
|
SKY_H: [
|
||||||
|
"class AAgrarianSkyLightingController : public AActor",
|
||||||
|
"TObjectPtr<UDirectionalLightComponent> SunLight;",
|
||||||
|
"TObjectPtr<USkyLightComponent> SkyLight;",
|
||||||
|
"TObjectPtr<UExponentialHeightFogComponent> HeightFog;",
|
||||||
|
"void RefreshSkyLighting();",
|
||||||
|
"float CalculateSunAlpha",
|
||||||
|
"float CalculateWeatherCloudAlpha",
|
||||||
|
],
|
||||||
|
SKY_CPP: [
|
||||||
|
"#include \"AgrarianGameState.h\"",
|
||||||
|
"SunLight = CreateDefaultSubobject<UDirectionalLightComponent>",
|
||||||
|
"SkyLight = CreateDefaultSubobject<USkyLightComponent>",
|
||||||
|
"HeightFog = CreateDefaultSubobject<UExponentialHeightFogComponent>",
|
||||||
|
"GameState->SunriseHourLocal",
|
||||||
|
"GameState->SunsetHourLocal",
|
||||||
|
"GameState->ActiveWeatherInputs.CloudCoverPercent",
|
||||||
|
"SunLight->SetWorldRotation",
|
||||||
|
"SunLight->SetIntensity",
|
||||||
|
"SkyLight->SetIntensity",
|
||||||
|
"HeightFog->SetFogDensity",
|
||||||
|
],
|
||||||
|
MAP_SETUP: [
|
||||||
|
"AGR_DemoSkyLightingController",
|
||||||
|
"unreal.AgrarianSkyLightingController",
|
||||||
|
"LEGACY_DEMO_LIGHTING_LABELS",
|
||||||
|
"\"AGR_DemoSun\"",
|
||||||
|
"\"AGR_DemoSkyLight\"",
|
||||||
|
"\"AGR_DemoFog\"",
|
||||||
|
],
|
||||||
|
TDD: [
|
||||||
|
"`AAgrarianSkyLightingController`",
|
||||||
|
"movable sun, skylight, and exponential-height-fog components",
|
||||||
|
],
|
||||||
|
ROADMAP: [
|
||||||
|
"[x] Add first-pass sky and lighting.",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
missing = []
|
||||||
|
for path, snippets in EXPECTED.items():
|
||||||
|
text = path.read_text(encoding="utf-8")
|
||||||
|
for snippet in snippets:
|
||||||
|
if snippet not in text:
|
||||||
|
missing.append(f"{path.relative_to(ROOT)}: {snippet}")
|
||||||
|
if missing:
|
||||||
|
raise RuntimeError("Sky lighting controller verification failed: " + "; ".join(missing))
|
||||||
|
print("Agrarian sky lighting controller verification complete.")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
// Copyright Pacificao. All Rights Reserved.
|
||||||
|
|
||||||
|
#include "AgrarianSkyLightingController.h"
|
||||||
|
|
||||||
|
#include "AgrarianGameState.h"
|
||||||
|
#include "Components/DirectionalLightComponent.h"
|
||||||
|
#include "Components/ExponentialHeightFogComponent.h"
|
||||||
|
#include "Components/SceneComponent.h"
|
||||||
|
#include "Components/SkyLightComponent.h"
|
||||||
|
#include "Engine/World.h"
|
||||||
|
|
||||||
|
AAgrarianSkyLightingController::AAgrarianSkyLightingController()
|
||||||
|
{
|
||||||
|
PrimaryActorTick.bCanEverTick = true;
|
||||||
|
bReplicates = false;
|
||||||
|
|
||||||
|
SceneRoot = CreateDefaultSubobject<USceneComponent>(TEXT("SceneRoot"));
|
||||||
|
RootComponent = SceneRoot;
|
||||||
|
|
||||||
|
SunLight = CreateDefaultSubobject<UDirectionalLightComponent>(TEXT("SunLight"));
|
||||||
|
SunLight->SetupAttachment(SceneRoot);
|
||||||
|
SunLight->SetIntensity(NoonSunIntensity);
|
||||||
|
SunLight->SetLightColor(FLinearColor(1.0f, 0.96f, 0.86f));
|
||||||
|
SunLight->SetMobility(EComponentMobility::Movable);
|
||||||
|
|
||||||
|
SkyLight = CreateDefaultSubobject<USkyLightComponent>(TEXT("SkyLight"));
|
||||||
|
SkyLight->SetupAttachment(SceneRoot);
|
||||||
|
SkyLight->SetIntensity(ClearSkyLightIntensity);
|
||||||
|
SkyLight->SetMobility(EComponentMobility::Movable);
|
||||||
|
|
||||||
|
HeightFog = CreateDefaultSubobject<UExponentialHeightFogComponent>(TEXT("HeightFog"));
|
||||||
|
HeightFog->SetupAttachment(SceneRoot);
|
||||||
|
HeightFog->SetFogDensity(ClearFogDensity);
|
||||||
|
HeightFog->SetMobility(EComponentMobility::Movable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AAgrarianSkyLightingController::BeginPlay()
|
||||||
|
{
|
||||||
|
Super::BeginPlay();
|
||||||
|
RefreshSkyLighting();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AAgrarianSkyLightingController::Tick(float DeltaSeconds)
|
||||||
|
{
|
||||||
|
Super::Tick(DeltaSeconds);
|
||||||
|
RefreshSkyLighting();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AAgrarianSkyLightingController::RefreshSkyLighting()
|
||||||
|
{
|
||||||
|
const UWorld* World = GetWorld();
|
||||||
|
const AAgrarianGameState* GameState = World ? World->GetGameState<AAgrarianGameState>() : nullptr;
|
||||||
|
if (!GameState)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float SunriseHour = GameState->bHasActiveTileSolarData ? GameState->SunriseHourLocal : 6.0f;
|
||||||
|
const float SunsetHour = GameState->bHasActiveTileSolarData ? GameState->SunsetHourLocal : 20.0f;
|
||||||
|
CurrentSunAlpha = CalculateSunAlpha(GameState->WorldHours, SunriseHour, SunsetHour);
|
||||||
|
CurrentWeather = GameState->Weather;
|
||||||
|
CurrentCloudAlpha = CalculateWeatherCloudAlpha(
|
||||||
|
GameState->Weather,
|
||||||
|
GameState->ActiveWeatherInputs.CloudCoverPercent,
|
||||||
|
GameState->ActiveWeatherInputs.bHasProviderData);
|
||||||
|
|
||||||
|
const float WeatherLightMultiplier = FMath::Lerp(1.0f, 0.35f, CurrentCloudAlpha);
|
||||||
|
const float SunIntensity = FMath::Lerp(NightSunIntensity, NoonSunIntensity, CurrentSunAlpha) * WeatherLightMultiplier;
|
||||||
|
const float SkyIntensity = FMath::Lerp(NightSkyLightIntensity, ClearSkyLightIntensity, CurrentSunAlpha) * FMath::Lerp(1.0f, 0.55f, CurrentCloudAlpha);
|
||||||
|
const float FogDensity = FMath::Lerp(ClearFogDensity, StormFogDensity, CurrentCloudAlpha);
|
||||||
|
const float SunPitch = FMath::Lerp(-8.0f, -72.0f, CurrentSunAlpha);
|
||||||
|
|
||||||
|
if (SunLight)
|
||||||
|
{
|
||||||
|
SunLight->SetWorldRotation(FRotator(SunPitch, NorthYawDegrees, 0.0f));
|
||||||
|
SunLight->SetIntensity(SunIntensity);
|
||||||
|
SunLight->SetLightColor(CalculateSunColor(CurrentSunAlpha, CurrentCloudAlpha));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SkyLight)
|
||||||
|
{
|
||||||
|
SkyLight->SetIntensity(SkyIntensity);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HeightFog)
|
||||||
|
{
|
||||||
|
HeightFog->SetFogDensity(FogDensity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float AAgrarianSkyLightingController::CalculateSunAlpha(float HourOfDay, float SunriseHour, float SunsetHour) const
|
||||||
|
{
|
||||||
|
const float NormalizedHour = FMath::Fmod(HourOfDay + 24.0f, 24.0f);
|
||||||
|
const float SafeSunrise = FMath::Fmod(SunriseHour + 24.0f, 24.0f);
|
||||||
|
const float SafeSunset = FMath::Fmod(SunsetHour + 24.0f, 24.0f);
|
||||||
|
const float DayLength = FMath::Max(0.1f, SafeSunset >= SafeSunrise ? SafeSunset - SafeSunrise : (24.0f - SafeSunrise) + SafeSunset);
|
||||||
|
|
||||||
|
float HoursSinceSunrise = NormalizedHour - SafeSunrise;
|
||||||
|
if (HoursSinceSunrise < 0.0f)
|
||||||
|
{
|
||||||
|
HoursSinceSunrise += 24.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HoursSinceSunrise > DayLength)
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float DayProgress = FMath::Clamp(HoursSinceSunrise / DayLength, 0.0f, 1.0f);
|
||||||
|
return FMath::Clamp(FMath::Sin(PI * DayProgress), 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
float AAgrarianSkyLightingController::CalculateWeatherCloudAlpha(EAgrarianWeatherType Weather, float ProviderCloudCoverPercent, bool bHasProviderCloudCover) const
|
||||||
|
{
|
||||||
|
float WeatherAlpha = 0.0f;
|
||||||
|
switch (Weather)
|
||||||
|
{
|
||||||
|
case EAgrarianWeatherType::Rain:
|
||||||
|
WeatherAlpha = 0.65f;
|
||||||
|
break;
|
||||||
|
case EAgrarianWeatherType::ColdWind:
|
||||||
|
WeatherAlpha = 0.45f;
|
||||||
|
break;
|
||||||
|
case EAgrarianWeatherType::Storm:
|
||||||
|
WeatherAlpha = 1.0f;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
WeatherAlpha = 0.0f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bHasProviderCloudCover)
|
||||||
|
{
|
||||||
|
WeatherAlpha = FMath::Max(WeatherAlpha, FMath::Clamp(ProviderCloudCoverPercent / 100.0f, 0.0f, 1.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
return WeatherAlpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
FLinearColor AAgrarianSkyLightingController::CalculateSunColor(float SunAlpha, float CloudAlpha) const
|
||||||
|
{
|
||||||
|
const FLinearColor DawnColor(1.0f, 0.62f, 0.38f);
|
||||||
|
const FLinearColor NoonColor(1.0f, 0.96f, 0.86f);
|
||||||
|
const FLinearColor StormColor(0.52f, 0.58f, 0.66f);
|
||||||
|
const FLinearColor TimeColor = FLinearColor::LerpUsingHSV(DawnColor, NoonColor, FMath::Clamp(SunAlpha, 0.0f, 1.0f));
|
||||||
|
return FLinearColor::LerpUsingHSV(TimeColor, StormColor, FMath::Clamp(CloudAlpha, 0.0f, 1.0f));
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
// Copyright Pacificao. All Rights Reserved.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "GameFramework/Actor.h"
|
||||||
|
#include "AgrarianTypes.h"
|
||||||
|
#include "AgrarianSkyLightingController.generated.h"
|
||||||
|
|
||||||
|
class UDirectionalLightComponent;
|
||||||
|
class UExponentialHeightFogComponent;
|
||||||
|
class USceneComponent;
|
||||||
|
class USkyLightComponent;
|
||||||
|
|
||||||
|
UCLASS(Blueprintable)
|
||||||
|
class AAgrarianSkyLightingController : public AActor
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
AAgrarianSkyLightingController();
|
||||||
|
|
||||||
|
virtual void BeginPlay() override;
|
||||||
|
virtual void Tick(float DeltaSeconds) override;
|
||||||
|
|
||||||
|
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Agrarian|Sky")
|
||||||
|
TObjectPtr<USceneComponent> SceneRoot;
|
||||||
|
|
||||||
|
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Agrarian|Sky")
|
||||||
|
TObjectPtr<UDirectionalLightComponent> SunLight;
|
||||||
|
|
||||||
|
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Agrarian|Sky")
|
||||||
|
TObjectPtr<USkyLightComponent> SkyLight;
|
||||||
|
|
||||||
|
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Agrarian|Sky")
|
||||||
|
TObjectPtr<UExponentialHeightFogComponent> HeightFog;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Sky")
|
||||||
|
float NoonSunIntensity = 8.0f;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Sky")
|
||||||
|
float NightSunIntensity = 0.03f;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Sky")
|
||||||
|
float ClearSkyLightIntensity = 1.0f;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Sky")
|
||||||
|
float NightSkyLightIntensity = 0.08f;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Sky")
|
||||||
|
float ClearFogDensity = 0.008f;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Sky")
|
||||||
|
float StormFogDensity = 0.05f;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Sky")
|
||||||
|
float NorthYawDegrees = -35.0f;
|
||||||
|
|
||||||
|
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Agrarian|Sky")
|
||||||
|
float CurrentSunAlpha = 0.0f;
|
||||||
|
|
||||||
|
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Agrarian|Sky")
|
||||||
|
float CurrentCloudAlpha = 0.0f;
|
||||||
|
|
||||||
|
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Agrarian|Sky")
|
||||||
|
EAgrarianWeatherType CurrentWeather = EAgrarianWeatherType::Clear;
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Agrarian|Sky")
|
||||||
|
void RefreshSkyLighting();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
float CalculateSunAlpha(float HourOfDay, float SunriseHour, float SunsetHour) const;
|
||||||
|
float CalculateWeatherCloudAlpha(EAgrarianWeatherType Weather, float ProviderCloudCoverPercent, bool bHasProviderCloudCover) const;
|
||||||
|
FLinearColor CalculateSunColor(float SunAlpha, float CloudAlpha) const;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user