Game.PlanetarySystem
Assembly: Assembly-CSharp
Namespace: Game.Simulation
Type: class
Base: GameSystemBase, IDefaultSerializable, ISerializable
Summary:
PlanetarySystem is a game system responsible for simulating astronomical bodies (sun, moon, night light) and updating their positions, orientations and lighting properties according to in-game time, geographic coordinates and atmosphere/prefab data. It integrates with the game's TimeSystem, RenderingSystem, CameraUpdateSystem and PrefabSystem to compute topocentric coordinates, render a moon texture, and apply lighting updates each frame. This system is important for day/night cycles, moon phases/appearance and related visual effects in Cities: Skylines 2 mods.
Fields
-
private static class ShaderIDs
Contains shader property ID constants used by the moon rendering material (e.g. _Camera2World, _CameraData, _SunDirection, _TexDiffuse, etc.). These are precomputed via Shader.PropertyToID for efficient shader parameter setting. -
private SunMoonData m_SunMoonData
Holds astronomical computation data and routines used to compute sun and moon positions. -
private TimeSystem m_TimeSystem
Reference to the game's TimeSystem used to read and compute time-of-day and time-of-year. -
private LightData m_SunLight
Wrapper struct representing the sun light GameObject, its Transform, Unity Light, HDAdditionalLightData and initial intensity. The struct tries to resolve the GameObject by tag when accessed. -
private LightData m_MoonLight
Similar wrapper for the moon light. -
private LightData m_NightLight
Wrapper for an optional night directional light used to simulate indirect/night illumination. -
private RenderingSystem m_RenderingSystem
Reference to the game's rendering system; used for frame indices and frame time. -
private CameraUpdateSystem m_CameraUpdateSystem
Reference to camera update system used to get the active camera for moon rendering. -
private PrefabSystem m_PrefabSystem
Used to fetch atmosphere-related prefabs (e.g. moon albedo/normal textures). -
private readonly float kDefaultLatitude
Default latitude constant (set to 41.9028f, Rome). -
private readonly float kDefaultLongitude
Default longitude constant (set to 12.4964f, Rome). -
private int m_Year
,m_Day
,m_Hour
,m_Minute
Stored in-game time components used to create DateTime for astronomical calculations. -
private float m_Second
Sub-second time component. -
private float m_Latitude
,m_Longitude
Geographic coordinates clamped to valid ranges via property setters. -
private int m_NumberOfLunarCyclesPerYear
Adjusts moon cycle frequency; validated to be non-negative. -
private RenderTexture m_MoonTexture
Render texture used to render the moon appearance at runtime. -
private Material m_MoonMaterial
Material used with a "Hidden/Satellites" shader to render and shade the moon. -
private int m_ClearPass
,m_LitPass
Pass indices on m_MoonMaterial for clearing and lit satellite rendering. -
private Vector2 m_OrenNayarCoefficients
Computed Oren–Nayar coefficients based on moon surface roughness for shading. -
private float m_SurfaceRoughness
Cached surface roughness used to calculate Oren–Nayar coefficients. -
private TypeHandle __TypeHandle
Compiler-generated handle structure (internal ECS plumbing). -
private EntityQuery __query_1383560598_0
,__query_1383560598_1
,__query_1383560598_2
Entity queries used to fetch TimeSettingsData, TimeData and AtmosphereData singletons from the ECS world.
Properties
-
public LightData SunLight { get; }
Access to the sun LightData. Reading resolves the GameObject by tag ("SunLight") lazily and returns whether it's valid via the LightData.isValid check. -
public LightData MoonLight { get; }
Access to the moon LightData ("MoonLight") and its resolved resources. -
public LightData NightLight { get; }
Access to night directional light LightData ("NightLight"). -
public bool overrideTime { get; set; }
When true, the system does not read global TimeSettings/TimeData and instead uses values directly set on this system (useful for forcing a particular time during editing or gameplay). -
public float latitude { get; set; }
World latitude used for astronomical calculations. Setter clamps to [-90, 90]. -
public float longitude { get; set; }
World longitude used for astronomical calculations. Setter clamps to [-180, 180]. -
public float debugTimeMultiplier { get; set; } = 1f
Multiplier applied to computed time-of-day (useful for debugging speeding/slowing the day-night cycle). -
public int year { get; set; }
Year component of simulated date. -
public int day { get; set; }
Day-of-year component (1..365). -
public int hour { get; set; }
Hour of day (0..23). -
public int minute { get; set; }
Minute component. -
public float second { get; set; }
Second component (fractions allowed). -
public float time { get; set; }
Convenience property to get/set time of day as float hours (e.g. 13.5 = 13:30). Setting updates hour/minute/second appropriately. -
public float dayOfYear { get; set; }
Day of year including fractional portion from normalizedTime. Setting decomposes into day and normalizedTime. -
public float normalizedDayOfYear { get; set; }
Normalized day of year in range [0,1), mapped to dayOfYear internally. -
public float normalizedTime { get; set; }
Normalized time-of-day in range [0,1), mapped to time internally. -
public int numberOfLunarCyclesPerYear { get; set; }
Number of lunar cycles per year; setter clamps to >= 0. -
public int moonDay { get; }
Computed moon day index based on day and numberOfLunarCyclesPerYear. -
public float moonSurfaceRoughness { get; set; }
Controls roughness used when rendering the moon; setter clamps to [0,1] and recalculates Oren–Nayar shading coefficients.
Constructors
public PlanetarySystem()
Default constructor. Most initialization happens in OnCreate (system lifecycle method). The constructor is marked with [Preserve] to avoid stripping.
Methods
-
protected override void OnCreate()
Initializes references to PrefabSystem, CameraUpdateSystem, TimeSystem, RenderingSystem; creates the moon RenderTexture and material (Hidden/Satellites shader), initializes LightData wrappers (tags "SunLight", "MoonLight", "NightLight"), and stores initial pass indices. Called when the system is created. -
protected override void OnDestroy()
Cleans up the moon render texture and material via CoreUtils.Destroy. Called when the system is destroyed. -
private static DateTime CreateDateTime(int year, int day, int hour, int minute, float second, float longitude)
Creates a UTC DateTime from the provided components and applies a longitude offset so astronomical calculations are correct for the specified meridian. -
private void UpdateTime(float date, float time, int year)
Sets normalizedDayOfYear, normalizedTime and year based on computed values from the TimeSystem. -
public TopocentricCoordinates GetSunPosition(DateTime date, double latitude, double longitude)
Wrapper to obtain the sun's topocentric coordinates for a given date and location via SunMoonData. -
public MoonCoordinate GetMoonPosition(DateTime date, double latitude, double longitude)
Wrapper to obtain moon coordinates via SunMoonData. -
protected override void OnUpdate()
Main per-frame update: - Reads and/or computes current time (either from local properties if overrideTime is true, or from TimeSettingsData/TimeData via ECS queries and TimeSystem).
- Computes sun position and updates the sun LightData Transform, rotation and intensity (intensity uses smoothstep based on sun altitude).
- Computes moon position and updates moon LightData Transform, rotation and distance. If sun data is available, calls RenderMoon() to update moon surface texture.
-
Updates NightLight Transform to align with the moon when present. This method depends on entity queries to fetch TimeSettingsData, TimeData and AtmosphereData singletons.
-
private void RenderMoon()
Renders the moon appearance to m_MoonTexture using m_MoonMaterial. It sets camera matrices and view-related shader parameters (camera corner data, sun direction, moon direction/tangent/bitangent, Oren–Nayar coefficients, luminance), samples atmosphere prefab textures for moon albedo and normal, executes clear and lit passes and assigns the produced RenderTexture to the moon light's additionalData.surfaceTexture. Requires an active camera, moon material and moon texture. -
public void SetDefaults(Context context)
Resets latitude & longitude to default constants (Rome). Called by serialization or context initialization code. -
public void Serialize<TWriter>(TWriter writer) where TWriter : IWriter
Serializes current latitude and longitude to the writer. -
public void Deserialize<TReader>(TReader reader) where TReader : IReader
Deserializes latitude and longitude from reader and writes into the fields. -
private void __AssignQueries(ref SystemState state)
Compiler-generated helper that builds EntityQuery instances used in OnUpdate to locate TimeSettingsData, TimeData and AtmosphereData singletons. -
protected override void OnCreateForCompiler()
Compiler helper that calls __AssignQueries and assigns type handles. Part of the ECS/IL2CPP compatibility and system bootstrap.
Usage Example
Example: Forcing a specific time and latitude to preview lighting and obtaining sun coordinates.
// Example: force midday over Rome and query sun direction
var planetarySystem = world.GetOrCreateSystemManaged<Game.Simulation.PlanetarySystem>();
planetarySystem.overrideTime = true;
planetarySystem.latitude = 41.9028f; // Rome latitude
planetarySystem.longitude = 12.4964f; // Rome longitude
planetarySystem.time = 12.0f; // midday
planetarySystem.day = 177; // day of year
planetarySystem.year = 2020;
// Force an update (normally called by the world)
planetarySystem.Update(); // if inside an ECS world, OnUpdate runs automatically each frame
// Get sun topocentric coordinates for current in-system time:
DateTime dt = new DateTime(0L, DateTimeKind.Utc)
.AddYears(planetarySystem.year - 1)
.AddDays(planetarySystem.day - 1)
.AddHours(planetarySystem.hour)
.AddMinutes(planetarySystem.minute)
.AddSeconds(planetarySystem.second)
.AddSeconds(-43200f * planetarySystem.longitude / 180f);
var sunCoords = planetarySystem.GetSunPosition(dt, planetarySystem.latitude, planetarySystem.longitude);
// sunCoords contains azimuth/altitude/local coordinates you can use for custom effects
Notes and tips: - LightData resolves GameObjects by tag on first access (SunLight, MoonLight, NightLight). Ensure corresponding GameObjects exist in the scene with those tags for the system to control them. - The moon rendering uses an internal shader "Hidden/Satellites" and relies on AtmospherePrefab textures (m_MoonAlbedo / m_MoonNormal). If you add custom atmosphere prefabs, they can affect moon appearance. - To preview day/night visuals in the Editor or for tools, set overrideTime = true and supply time/latitude/longitude on this system.