Skip to content

Game.WeatherAudioSystem

Assembly: Game
Namespace: Game.Audio

Type: class

Base: GameSystemBase

Summary:
WeatherAudioSystem is a managed game system responsible for handling small-scale water ambient audio that follows the camera (e.g., shore/near-water ambient sound). It updates on a multi-frame interval (GetUpdateInterval returns 16) and, when active, schedules a Burst-compiled job (WeatherAudioJob) to check whether the active camera is near water and to update an EffectInstance and audio source transform accordingly. The system integrates with TerrainSystem, WaterSystem, CameraUpdateSystem and AudioManager, and uses component lookups and NativeArray water depth data provided by the WaterSystem to determine proximity. Note: much of the system is driven by ECS data (WeatherAudioData singleton) and private fields/components; modders should interact via the WeatherAudioData component or by obtaining the system through the World API.


Fields

  • private AudioManager m_AudioManager
    Handles creation/updates of audio sources and provides the SourceUpdateData used by the job. The system obtains a SourceUpdateData writer when scheduling the job.

  • private TerrainSystem m_TerrainSystem
    Used to sample terrain height (TerrainHeightData) so the water audio effect instance can be positioned at the camera's ground height.

  • private WaterSystem m_WaterSystem
    Provides water texture size and water depth NativeArray used by the NearWater check as well as whether water system is loaded. Water depth array access is scheduled with a dependency.

  • private CameraUpdateSystem m_CameraUpdateSystem
    Used to query the active viewer position and active camera controller (zoom) to decide whether the small water audio should be active.

  • private EntityQuery m_WeatherAudioEntityQuery
    Query used to find the singleton WeatherAudioData component that configures water audio behavior (e.g., enabled zoom, near distance, intensity, fade speed, prefab).

  • private Entity m_SmallWaterAudioEntity
    Entity that holds the EffectInstance and PrefabRef for the small/ambient water audio. Created in Initialize() from WeatherAudioData.m_WaterAmbientAudio.

  • private int m_WaterAudioEnabledZoom
    Cached value from WeatherAudioData indicating the zoom threshold below which the small water audio should be active.

  • private int m_WaterAudioNearDistance
    Cached value from WeatherAudioData that defines how many water texture cells around the camera are checked to consider the camera "near water."

  • private TypeHandle __TypeHandle
    Internal struct instance used to cache ComponentLookup handles (e.g., EffectInstance lookup) for use inside jobs and compiler-generated helper paths.


Properties

  • None. All state is stored in private fields and ECS components.

Constructors

  • public WeatherAudioSystem()
    Default constructor. The system is marked with [CompilerGenerated] in the decompiled source; OnCreate and OnCreateForCompiler perform the initialization of queries and type handles. No special construction logic beyond base initialization.

Methods

  • public override int GetUpdateInterval(SystemUpdatePhase phase)
    Returns 16. The system is scheduled to run once every 16 game update ticks (so it performs work at a lower frequency than every frame).

  • protected override void OnCreate()
    Acquires references to required managed systems (AudioManager, TerrainSystem, WaterSystem, CameraUpdateSystem) via World.GetOrCreateSystemManaged<...>(). Constructs an EntityQuery for WeatherAudioData and calls RequireForUpdate on that query so the system only runs when that data exists.

  • protected override void OnGameLoaded(Context serializationContext)
    Resets m_SmallWaterAudioEntity to Entity.Null when a game is loaded. Ensures the audio entity will be re-created/initialized on next update.

  • private void Initialize()
    Creates the small water audio entity: adds an EffectInstance component and a PrefabRef whose prefab is taken from the WeatherAudioData.m_WaterAmbientAudio field. Also caches WeatherAudioData settings (m_WaterAudioEnabledZoom and m_WaterAudioNearDistance) into private fields for quicker checks during updates.

  • protected override void OnUpdate()
    Main update routine. Behavior:

  • Ensures water system is loaded and there is an active camera viewer/controller.
  • Creates/initializes the small water audio entity if missing.
  • If the small water audio entity has an EffectInstance component and the camera zoom is less than the configured enabled zoom:
    • Builds a WeatherAudioJob with:
    • water texture size
    • camera position
    • water audio entity
    • WeatherAudioData singleton
    • SourceUpdateData (from AudioManager) — writer + dependency
    • TerrainHeightData (from TerrainSystem)
    • ComponentLookup (via cached TypeHandle)
    • Water depth NativeArray (from WaterSystem) — reader + dependency
    • Schedules the job with combined dependencies and sets base.Dependency.
    • Registers the dependency with TerrainSystem (AddCPUHeightReader) and AudioManager (AddSourceUpdateWriter).
  • If zoom is too far or other conditions aren't met, the job is not scheduled, and the system will eventually fade out and remove the source via the job logic when appropriate.

  • protected override void OnCreateForCompiler()
    Compiler-generated helper invoked for initialization steps in the generated code path. Calls __AssignQueries and assigns type handles via __TypeHandle.__AssignHandles.

  • private void __AssignQueries(ref SystemState state)
    Compiler helper for registering queries; here it contains a no-op EntityQueryBuilder disposal (decompiled artifact).

  • private struct TypeHandle
    Contains cached ComponentLookup named __Game_Effects_EffectInstance_RW_ComponentLookup and provides __AssignHandles(ref SystemState state) to populate the lookup from state.GetComponentLookup().

Nested types and jobs: - private struct WeatherAudioJob : IJob (BurstCompile)
- Executes the core logic on a worker thread under Burst: - NearWater(...) checks the water depth texture cells around the camera; if any depth > 0, considers camera near water. - If near water: - Reads current EffectInstance for the small water audio entity, samples terrain height under camera, interpolates/moves intensity toward WeatherAudioData.m_WaterAudioIntensity based on m_WaterFadeSpeed, sets position/rotation/intensity, writes back to the EffectInstance component, and adds a source transform update via m_SourceUpdateData.Add. - If not near water but the entity still has an EffectInstance: - If intensity is already very low (<= 0.01), removes the source update (m_SourceUpdateData.Remove). - Otherwise, fades intensity toward zero using m_WaterFadeSpeed, updates the EffectInstance, and writes a transform update. - Notes: - Uses TerrainUtils.SampleHeight(ref TerrainHeightData, position) to sample ground height for positioning the audio effect. - Uses math.saturate and math.lerp for intensity clamping and interpolation. - The NearWater method maps world position to water texture cell coordinates using WaterSystem.GetCell and checks a surrounding square region limited by m_WaterAudioNearDistance. It clamps indices to texture bounds and indexes the depths NativeArray.


Usage Example

// Example: adjust the water audio intensity and near-distance at runtime.
// This runs from any mod code that has access to the game's World and EntityManager.

public void ChangeWaterAudioSettings(World world, float newIntensity, int newNearDistance)
{
    var em = world.EntityManager;
    // Get the singleton entity that holds WeatherAudioData
    var weatherEntity = em.CreateEntityQuery(typeof(WeatherAudioData)).GetSingletonEntity();

    // Read, modify and write back the WeatherAudioData component
    var data = em.GetComponentData<WeatherAudioData>(weatherEntity);
    data.m_WaterAudioIntensity = newIntensity;
    data.m_WaterAudioNearDistance = newNearDistance;
    em.SetComponentData(weatherEntity, data);
}

// Example: obtain the WeatherAudioSystem (if you need to call methods or force initialization)
var weatherSystem = world.GetOrCreateSystemManaged<Game.Audio.WeatherAudioSystem>();
// Note: most behavior is driven by WeatherAudioData; many fields in WeatherAudioSystem are private.

Notes and Modding Tips: - The system updates infrequently (every 16 ticks) to reduce cost. Changes to WeatherAudioData take effect on the next system run. - The actual audio source entity created by Initialize holds EffectInstance and PrefabRef components. If you need to replace the prefab, change WeatherAudioData.m_WaterAmbientAudio. - WeatherAudioJob is Burst-compiled and reads NativeArray water depths; be mindful of scheduling/dependencies when interacting with WaterSystem/TerrainSystem to avoid race conditions. Use the ECS APIs (EntityManager, component data) rather than attempting to modify internal private fields of the system instance.