Spawning vs. Object Motion
The Elastic Graph operates on a strictly location-dependent model, creating and spawning active assets programmatically at static coordinate boundaries across the landscape. However, once spawned, those objects remain permanently stationary unless animated or moved programmatically.
To deliver an immersive, dynamic passenger experience, you must decouple static coordinate spawning from runtime, time-dependent simulation loops.
1. Managing Time-Dependent Effects
Because the Graph does not compile, tick, or refresh based on elapsed frames or delta-time, any progressive or frame-based animations must be offloaded to traditional, runtime Unity systems:
---
config:
flowchart:
subGraphTitleMargin:
bottom: 30
---
flowchart TD
subgraph Graph_Pipeline ["1. Elastic Graph Scope (Location-Dependent Only)"]
OSM["OSM Geographic Data"]
GPS["GPS Location Transitions"]
Graph["Elastic Graph Evaluation <br> (Only recalculates when vehicle moves!)"]
Spawning["Procedural Spawning <br> (Spawns Prefabs at static coordinates)"]
OSM & GPS --> Graph
Graph --> Spawning
end
subgraph Unity_Runtime ["2. Unity Game Scope (Time-Dependent & Motion)"]
Mono["MonoBehaviours / Update Loop <br> (Ticks time, handles steering, moves assets)"]
Shader["Shader Time-Variables <br> (Flowing liquids, wind, flickering light)"]
Post["Post-Processing <br> (Color grading shifts over time)"]
end
Spawning -->|Initial Spawning Anchor| Mono
subgraph Code_Bridge ["3. Programmatic Sampling (The Bridge)"]
Sample["Map Sampling API <br> (NPCs query terrain height to stay grounded)"]
end
Mono -->|Programmatic Query| Sample
Graph -->|Provides heights & masks| Sample
%% Styling (Vibrant, highly colored borderless theme)
style Graph_Pipeline fill:#e0f2fe,stroke-width:0px
style OSM fill:#0284c7,stroke-width:0px,color:#fff
style GPS fill:#0ea5e9,stroke-width:0px,color:#fff
style Graph fill:#06b6d4,stroke-width:0px,color:#fff
style Spawning fill:#0891b2,stroke-width:0px,color:#fff
style Unity_Runtime fill:#f3e8ff,stroke-width:0px
style Mono fill:#7c3aed,stroke-width:0px,color:#fff
style Shader fill:#9c27b0,stroke-width:0px,color:#fff
style Post fill:#8b5cf6,stroke-width:0px,color:#fff
style Code_Bridge fill:#dcfce7,stroke-width:0px
style Sample fill:#16a34a,stroke-width:0px,color:#fff
- Traditional MonoBehaviours: Use standard Unity scripts (
Update(), coroutines, or state machines) to drive ticking behaviors, rotators, time-of-day progression, or object growth. - Time-Dependent Shaders: Use standard Unity shader time variables (like
_Time) inside your materials to animate flowing water, moving clouds, rustling foliage, or flickering light emitters. - Color and Atmospheric Shifts: Utilize Unity post-processing volumes and scripts to smoothly change the color grading, lens vignette, or fog density over time to simulate sunsets, weather changes, or night cycles.
2. Spawning vs. Object Motion (Animating NPCs)
Since the graph only handles initial coordinate spawning, to implement moving animals, pedestrian NPCs, or virtual traffic vehicles inside your procedural world, apply the following decoupling strategies:
MonoBehaviour AI & Steering
Attach a standard Unity movement or steering script (e.g., waypoint following, AI steering, pathfinding, or kinematic controllers) directly to your spawned prefab asset.
Because the prefab is a standard Unity asset, its scripts can compile, tick, and execute standard frame-by-frame updates (Update() or FixedUpdate()) completely independently of the background generation thread.
Programmatic Map Sampling
To prevent moving NPCs from clipping through procedurally sculpted mountains or walking under the ground mesh, your movement scripts must query the active terrain height dynamically.
By querying the active heightmap at the NPC's current coordinate every frame, your scripts can smoothly adjust the GameObject's vertical (Y) transform coordinate to match the terrain slope:
// Programmatic map query inside your NPC Update loop
var samplePos = new GlobalPosition(transform.position);
float terrainHeight = this.myMapSampler.SampleMapValue(transform.position);
transform.position = new Vector3(transform.position.x, terrainHeight, transform.position.z);
For a detailed, step-by-step walkthrough on setting up programmatic graph reading inside your movement scripts, refer to the Sample Map Nodes via Code guide inside the Code reference.