Game.Rendering.MeshColorSystem
Assembly: Assembly-CSharp
Namespace: Game.Rendering
Type: class
Base: GameSystemBase
Summary:
MeshColorSystem is the ECS system responsible for computing and updating per-mesh color data for game entities (buildings, vehicles, characters, plants, etc.). It collects entities that need color updates, runs burst-compiled jobs to determine color variations (including syncing colors across groups, applying filters, seasonal blending and external sources like brands or routes), and writes MeshColor buffers. The system supports overrides (for preview/rendering different prefab/variation), incremental updates, and copying color data from external sources when ColorSourceType.Parent/Brand is used. It also exposes utilities for randomizing colors/alphas used by the jobs.
Fields
-
private ClimateSystem m_ClimateSystem
Reference to the ClimateSystem used to determine seasonal colors and blending. -
private SimulationSystem m_SimulationSystem
Reference to the SimulationSystem (used for frameIndex grouping and update scheduling). -
private PrefabSystem m_PrefabSystem
Reference to PrefabSystem to resolve prefab entities and data. -
private RenderPrefabBase m_OverridePrefab
If set, a prefab to use as an override when computing mesh colors (used together with m_OverrideEntity and m_OverrideIndex). -
private Dictionary<string, int> m_GroupIDs
Local map storing string -> int ids for ColorGroupID lookups. -
private EntityQuery m_UpdateQuery
Query that finds mesh color entities that were updated (events) and therefore need color recomputation. -
private EntityQuery m_AllQuery
Query for all entities that have a MeshColor buffer (used for full recompute). -
private EntityQuery m_PlantQuery
Query optimized for plant smoothing updates (plants updated via UpdateFrame shared component). -
private EntityQuery m_BuildingSettingsQuery
Query to access building configuration settings (e.g. default brand). -
private Entity m_LastSeason1
Last sampled season prefab entity (used for seasonal blending). -
private Entity m_LastSeason2
Second season prefab entity used for blending. -
private Entity m_OverrideEntity
Entity for which an override prefab/variation is currently applied. -
private uint m_LastUpdateGroup
Internal group id used for spreading updates across frames. -
private uint m_UpdateGroupCount
Counter controlling how many groups must still be updated (used with seasonal changes). -
private int m_OverrideIndex
Variation index used when m_OverridePrefab is set. -
private float m_LastSeasonBlend
Packed blend value representing seasonal blend state. -
private bool m_Loaded
Flag set when the game load event occurs; triggers a full recompute on next update. -
private TypeHandle __TypeHandle
Internal struct holding ECS Type/Buffer/Component handles used by scheduled jobs.
Properties
public bool smoothColorsUpdated { get; private set; }
Indicates whether a "smooth" color update (plants smoothing / partial updates) was scheduled during the last OnUpdate. Readable by other systems to detect small incremental updates.
Constructors
public MeshColorSystem()
Default constructor. The system is marked with [Preserve] and initialized by the ECS world; actual initialization of queries and references occurs in OnCreate.
Methods
-
protected override void OnCreate()
Initializes dependent systems (ClimateSystem, SimulationSystem, PrefabSystem), creates entity queries (m_UpdateQuery, m_AllQuery, m_PlantQuery, m_BuildingSettingsQuery) and prepares the internal group-ID dictionary. Called when the system is created. -
protected override void OnGameLoaded(Context serializationContext)
Sets an internal flag to trigger a full update on the next OnUpdate after a save/load. -
private bool GetLoaded()
Helper that returns and clears the internal m_Loaded flag. Used to detect first update after game load. -
public void SetOverride(Entity entity, RenderPrefabBase prefab, int variationIndex)
Request the system to use a preview/override prefab + variation for a specific entity. If there was an existing override entity, the previous entity will get a BatchesUpdated component so rendering updates are applied. -
protected override void OnUpdate()
Main update that: - Determines if a full recompute or incremental recompute is needed (based on loaded flag, event queries, plant updates, seasonal changes).
- Builds an entity list to update (either all MeshColor entities, plants-only group, or a list of entities flagged by events).
- Schedules three main jobs:
- FindUpdatedMeshColorsJob: finds entities needing updates (handles nested subobjects, route vehicles and layout elements).
- SetMeshColorsJob: burst job that computes mesh color values for each MeshColor entry of entities. Handles randomization, sync groups, external channel copying, color filters, seasonal blending, and override handling.
- CopyMeshColorsJob: processes queued CopyColorData items to copy and apply variation ranges/alpha changes from source mesh colors to target mesh colors.
-
Manages job dependencies, queues and disposals.
-
public ColorGroupID GetColorGroupID(string name)
Returns a ColorGroupID for a given string name. Internally maintains m_GroupIDs and assigns incremental ids for previously unseen names. -
private static void RandomizeColor(ref UnityEngine.Color color, ref Unity.Mathematics.Random random, float3 min, float3 max)
Converts the given color to HSV, applies random per-channel multipliers in the provided range (min..max), and writes back the color (preserving alpha). Used by job code to apply variation ranges. -
private static void RandomizeAlphas(ref ColorSet colorSet, ref Unity.Mathematics.Random random, float3 min, float3 max)
Randomizes the alpha channels of the three ColorSet channels by adding a random offset per-channel (clamped to [0,1]). Used by job code to apply alpha variation. -
protected override void OnCreateForCompiler()
Internal method used to ensure TypeHandle is assigned for compiled builds (calls __AssignQueries and assigns handles). Present in the compiled class to satisfy job setup. -
private void __AssignQueries(ref SystemState state)
Internal placeholder used to instantiate EntityQueryBuilder in builds compiled for the job-system; not typically called by modders. -
Nested job structs:
- FindUpdatedMeshColorsJob (IJobChunk, BurstCompile): iterates event chunks, adds entities to a queue for further processing. Walks subobjects recursively and resolves route vehicles and layout elements.
- ListUpdatedMeshColorsJob (IJob, BurstCompile): dequeues the queue written by FindUpdatedMeshColorsJob, produces a sorted unique NativeList
. - SetMeshColorsJob (IJobParallelForDefer, BurstCompile): core color computation job. Uses many ComponentLookup/BufferLookup references. Handles:
- Iterating submeshes / submesh groups and overlay elements
- Building per-color SyncData for handling ColorSyncFlags (SameGroup/SameIndex/etc)
- Selecting ColorVariation entries using seeded random, color filters, season blending and overrides
- Queuing CopyColorData entries when external channels or Parent sources must copy color from other entities
- CopyMeshColorsJob (IJob, BurstCompile): consumes the queued CopyColorData items and applies copied colors (including applying per-channel variation/alpha ranges).
- CopyColorData: POD struct passed between jobs describing a copy operation (source, target, seed, indexes and ranges).
Notes: - The system relies heavily on ECS BufferLookup/ComponentLookup APIs and deferred job arrays for parallelism and burst compilation. - Color synchronization across submeshes is implemented via SyncData written during SetMeshColorsJob and used to pick matching colors within groups. - External color sources include Brand (companies), Route color, and Parent (owner chain). If no brand is found where requested, the building default brand may be used.
Usage Example
// Simple use: override colors for a single entity (e.g. when previewing a prefab variation)
var meshColorSystem = World.DefaultGameObjectInjectionWorld.GetExistingSystemManaged<Game.Rendering.MeshColorSystem>();
Entity previewEntity = /* entity you want to preview */;
RenderPrefabBase overridePrefab = /* the prefab to preview */;
int variationIndex = 2;
meshColorSystem.SetOverride(previewEntity, overridePrefab, variationIndex);
// Example: request a named color group id (used when defining ColorVariation groups)
ColorGroupID roofGroup = meshColorSystem.GetColorGroupID("RoofGroup");
If you need an example of how to react to smoothColorsUpdated or how to force a full recompute from another system, let me know and I can add a sample snippet.