Game.Debug.TreeSpawnSystem
Assembly:
Namespace: Game.Debug
Type: class
Base: GameSystemBase
Summary:
This system runs at the start of a new game to procedurally place a batch of tree entities across the terrain. It selects random tree prefabs, samples terrain height, assigns a transform and tree component (state and growth), then creates entities using the prefab archetype. Execution is gated so it only runs for a new game (LoadGameSystem.context.purpose == Purpose.NewGame) and only when there are no existing Tree entities. It allocates a temporary NativeArray of prefab entities and disposes it when done. This is a main-thread, non-jobified setup that creates 5000 trees in a single update.
Fields
-
private LoadGameSystem m_LoadGameSystem
This references the LoadGameSystem so the TreeSpawnSystem can check the current loading context/purpose (to run only for new games). -
private TerrainSystem m_TerrainSystem
Used to fetch TerrainHeightData (with waitForPending: true) so tree positions can have their Y coordinate sampled against the terrain height. -
private EntityQuery m_Prefabs
An EntityQuery selecting available tree prefabs (requires TreeData and excludes PlaceholderObjectElement). The system uses this query to pick random prefab entities to instantiate. -
private EntityQuery m_TreeQuery
An EntityQuery selecting existing Tree entities. The system checks this to ensure it does not spawn trees when trees already exist.
Properties
- None
Constructors
public TreeSpawnSystem()
Default parameterless constructor. The system is marked with [Preserve] on lifecycle methods to avoid code stripping.
Methods
protected override void OnCreate()
: System.Void
Initializes references to LoadGameSystem and TerrainSystem, creates the entity queries for tree prefabs and existing trees, and calls RequireForUpdate(m_Prefabs) so the system only runs when tree prefabs are available. Marked with [Preserve].
Additional notes:
- m_Prefabs uses ComponentType.ReadOnly
protected override void OnUpdate()
: System.Void
Main spawning logic. Behaviour summary:- Returns early unless the load context purpose is Purpose.NewGame and there are no existing Tree entities.
- Seeds a Unity.Mathematics.Random with (uint)DateTime.Now.Ticks.
- Retrieves TerrainHeightData from TerrainSystem with waitForPending: true.
- Converts m_Prefabs query to a temporary NativeArray
(Allocator.TempJob) and iterates 5000 times: - Picks a random prefab Entity from the prefab array.
- Reads the prefab's ObjectData component to obtain the archetype for instantiation.
- Chooses a random XZ position within [-1000, 1000], samples the terrain height for Y, and sets a random Y-rotation.
- Randomly assigns TreeState (seedling/teen/adult/elderly/dead) using random.NextInt(13) with a weighted mapping, and a random growth byte (0–255).
- Creates a new entity using the prefab archetype and sets PrefabRef, Transform, and Tree components accordingly.
- Ensures the temporary NativeArray is disposed in a finally block.
Important implementation details and cautions: - Creates 5000 entities in one update — may cause a noticeable hitch during new-game initialization depending on performance and archetype complexity. - Uses Allocator.TempJob for the NativeArray; it is explicitly disposed in finally. - Random seed uses DateTime.Now.Ticks cast to uint — this is a lossy cast but acceptable here for basic randomness. - The system runs on the main thread and uses EntityManager.SetComponentData / CreateEntity (no parallel instantiation or jobs).
Usage Example
[Preserve]
protected override void OnCreate()
{
base.OnCreate();
m_LoadGameSystem = base.World.GetOrCreateSystemManaged<LoadGameSystem>();
m_TerrainSystem = base.World.GetOrCreateSystemManaged<TerrainSystem>();
m_Prefabs = GetEntityQuery(ComponentType.ReadOnly<TreeData>(), ComponentType.Exclude<PlaceholderObjectElement>());
m_TreeQuery = GetEntityQuery(ComponentType.ReadOnly<Tree>());
RequireForUpdate(m_Prefabs);
}
// When a new game starts and there are no trees, OnUpdate will create ~5000 trees:
// It picks random prefabs from m_Prefabs, samples terrain height, assigns a random TreeState
// and growth value, then creates entities using the prefab archetype.