Game.Rendering.Climate.WeatherPropertiesStack
Assembly: Assembly-CSharp
Namespace: Game.Rendering.Climate
Type: internal class
Base: System.IDisposable
Summary:
WeatherPropertiesStack manages a runtime/interpolated representation of all OverrideablePropertiesComponent-derived weather property components (clouds, fog, precipitation, etc.). It creates ScriptableObject instances for each component type, binds them to an optional Volume, and provides facilities to set "target", "from", "to" and "previous" states and to advance/interpolate those states over real-time or rendering-time. The class also supports non-time-based interpolation modes (Cloudiness, Precipitation, Aurora) by remapping climate sample values into a lerp, and it is responsible for cleaning up the created ScriptableObjects when disposed.
Fields
-
private UnityEngine.Rendering.Volume m_Volume
Holds the Volume instance used to Bind created OverrideablePropertiesComponent instances. May be null if no volume was provided to the constructor. -
public readonly System.Collections.Generic.Dictionary<Type, InterpolatedProperties> components
Dictionary mapping each OverrideablePropertiesComponent-derived Type to its interpolated representation (an InterpolatedProperties instance). The dictionary is populated by discovering all non-abstract OverrideablePropertiesComponent types at construction.
Additional (inner) type: InterpolatedProperties — holds per-component interpolation state: - time: current normalized interpolation time [0..1]. - remapLimits: Bounds1 used to remap sample values for certain interpolation modes (e.g., cloudiness). - current, previous, target, from, to: ScriptableObject instances (OverrideablePropertiesComponent) used in interpolation. - source: internal reference to the original/source component used to set target/to.
(See InterpolatedProperties members in Methods section below.)
Properties
- There are no public properties on WeatherPropertiesStack. The components field is public readonly for external inspection.
Constructors
public WeatherPropertiesStack(UnityEngine.Rendering.Volume volume = null)
Creates a new WeatherPropertiesStack. If a Volume is provided, created OverrideablePropertiesComponent instances are bound to it. The constructor calls CreateInterpolatedRepresentation to instantiate and bind per-component ScriptableObjects for all OverrideablePropertiesComponent-derived types.
Methods
-
private void CreateInterpolatedRepresentation()
Discovers all non-abstract types derived from OverrideablePropertiesComponent (via CoreUtils.GetAllTypesDerivedFrom()), creates five ScriptableObject instances per type (current, previous, target, from, to), binds the primary/current instance to m_Volume, and stores an InterpolatedProperties object in components for each type. This prepares the stack for runtime interpolation. -
public void SetTarget(Type type, OverrideablePropertiesComponent target)
Sets the target OverrideablePropertiesComponent instance for the given component type. The provided target is copied into the stored target instance, the source is tracked, and the stored "previous" is updated to the current state. -
public void SetTo(Type type, OverrideablePropertiesComponent to, bool setLimits, Colossal.Mathematics.Bounds1 limits)
Sets the "to" component used in non-time-based interpolation for the given type. If setLimits is true, remapLimits is set to the provided limits (used for remapping cloudiness -> lerp). The stored "previous" is updated to the current state. -
public void SetFrom(Type type, OverrideablePropertiesComponent from)
Sets the "from" component used in non-time-based interpolation for the given type and updates "previous" to the current state. -
public void InterpolateOverrideData(float deltaTime, float renderingDeltaTime, Game.Simulation.ClimateSystem.ClimateSample sample, bool editMode)
Main update method that performs interpolation for all component types whose target.active is true. For each: - If the stored
to
does not use time-based interpolation, it computes a lerp via InterpolatedProperties.GetLerp(sample) and overrides target from/from->to accordingly. - If editMode is true, the stored source is overwritten with the current target (useful for editor workflows).
- The stored current instance is updated by interpolating previous -> target using the stored time value.
-
Advance() is called to increment the interpolation time according to the interpolation mode (RealTime vs RenderingTime) and the appropriate delta (deltaTime or renderingDeltaTime).
-
public void Dispose()
Destroys all created ScriptableObject instances (current, previous, target, from, to for each component) using CoreUtils.Destroy and clears the components dictionary. Must be called when the stack is no longer needed to avoid leaking ScriptableObjects.
Inner class: InterpolatedProperties (per-component interpolation state)
- Constructor:
- public InterpolatedProperties(OverrideablePropertiesComponent current, OverrideablePropertiesComponent previous, OverrideablePropertiesComponent target, OverrideablePropertiesComponent from, OverrideablePropertiesComponent to)
Initializes the per-component containers used during interpolation.
- Methods and behavior:
-
private static float Remap(float value, float from1, float to1, float from2, float to2)
Helper to remap and saturate a value from one range to another (used for cloudiness remapping). -
public void SetTarget(OverrideablePropertiesComponent newTarget)
Copies newTarget into the stored target instance, stores source reference, copies interpolation mode/time from source into target, and resets time to 0. -
public void SetPrevious(OverrideablePropertiesComponent newSource)
Copies newSource into previous and resets time to 0. -
public void SetTo(OverrideablePropertiesComponent newTo)
Copies newTo into stored to, stores source reference, copies interpolation mode/time from source into to, and resets time to 0. -
public void SetFrom(OverrideablePropertiesComponent newFrom)
Copies newFrom into stored from and resets time to 0. -
public void Advance(float deltaTime, float renderingDeltaTime)
Increments time (normalized 0..1) using either deltaTime or renderingDeltaTime depending on target.m_InterpolationMode. If target.m_InterpolationMode is RealTime, uses deltaTime / target.m_InterpolationTime; if RenderingTime, uses renderingDeltaTime / target.m_InterpolationTime. math.saturate is used to clamp to [0,1]. -
public float GetLerp(Game.Simulation.ClimateSystem.ClimateSample sample)
Returns a lerp value based on to.m_InterpolationMode:- Cloudiness: remaps sample.cloudiness from remapLimits to [0..1] using Remap.
- Precipitation: returns sample.precipitation.
- Aurora: returns sample.aurora.
- Default: returns 1.0f.
Notes about interpolation behavior:
- If to.hasTimeBasedInterpolation is false, interpolation between from
and to
is controlled by sampling-based lerp (Cloudiness/Precipitation/Aurora) rather than by the time field.
- The code uses OverrideablePropertiesComponent.Override(...) overloads to copy/compose values between ScriptableObjects (target.Override(from, to, lerp), current.Override(previous, target, time), etc.).
- Created component instances are ScriptableObjects; they are destroyed in Dispose to avoid leaks.
Usage Example
// Create the stack (optionally bind to a Volume)
var weatherStack = new WeatherPropertiesStack(myVolume);
// Set a new target for a component type (e.g., Cloud properties)
weatherStack.SetTarget(typeof(MyCloudPropertiesComponent), someCloudPropsInstance);
// For sample-driven interpolation (non-time-based), set from/to and remap limits
weatherStack.SetFrom(typeof(MyCloudPropertiesComponent), fromProps);
weatherStack.SetTo(typeof(MyCloudPropertiesComponent), toProps, setLimits: true, limits: new Bounds1(0f, 1f));
// During update: advance interpolation (real-time delta + rendering delta) using current climate sample
weatherStack.InterpolateOverrideData(deltaTime, renderingDeltaTime, climateSample, editMode: false);
// When done, dispose to destroy created ScriptableObjects
weatherStack.Dispose();
Additional tips: - Because the class creates ScriptableObject instances for every OverrideablePropertiesComponent-derived type, keep a single WeatherPropertiesStack and dispose it when the mod or scene unloads. - The class depends on CoreUtils and OverrideablePropertiesComponent implementations present in the game; its behavior assumes those OverrideablePropertiesComponent APIs (Override, m_InterpolationMode, m_InterpolationTime, hasTimeBasedInterpolation, active, etc.). - Use editMode=true when you want the source instances to be updated live with the target (useful for in-editor adjustments).