Runtime Samples
Samples showcasing Flora's runtime features.
Fish Boids
The Fish Boids sample scene demonstrates how to use Flora for large-scale, runtime-driven instance animation by adapting Unity’s original ECS BoidSample. It showcases how to spawn, update, and synchronize thousands of animated instances efficiently — with full support for motion vectors.

Key Concepts
Each fish is represented as a Flora instance, without requiring GameObjects.
Boid movement is simulated using jobs and native collections, then synced to Flora each frame.
Flora handles rendering, culling, batching, and motion vectors automatically.
Core Classes
FishSchool
NativeArray<FloraInstanceTransform> m_Transforms; // Transform storage
NativeArray<FloraInstanceHandle> m_InstanceHandles; // Handle storage (instance id)
JobHandle m_Dependency; // Update job dependency
void OnEnable()
{
// Create the native storage for the instance handles and transforms
m_Transforms = new NativeArray<FloraInstanceTransform>(SpawnCount, Allocator.Persistent);
m_InstanceHandles = new NativeArray<FloraInstanceHandle>(SpawnCount, Allocator.Persistent);
// A simple job that distributes the instances within a sphere
new InitFishTransformsJob {
Seed = (uint)UnityEngine.Random.Range(0, int.MaxValue),
Center = transform.position,
Radius = transform.localScale.x * SpawnRadius,
FishTransforms = m_Transforms,
}.Schedule(m_Transforms.Length, 64).Complete();
// Register the fish instances with the Flora system
FloraSystem.GetOrCreate().CreateInstances(Prefab, gameObject, m_InstanceHandles, m_Transforms);
}
void OnDisable()
{
// Ensure the job is completed before destroying the instances
m_Dependency.Complete();
// Destroy the fish instances in the Flora system
FloraSystem.Instance?.DestroyInstances(m_InstanceHandles);
// Dispose our native data
m_Transforms.Dispose();
m_InstanceHandles.Dispose();
}
/// <summary>
/// Uploads the local-to-world matrices to the Flora system.
/// </summary>
public void CompleteAndUpload()
{
// This dependency is used by the fish simulation,
// make sure it's done before uploading the instances
m_Dependency.Complete();
// The main function for changing instance transforms
FloraSystem.Instance?.UpdateInstanceWorldTransforms(m_InstanceHandles, m_Transforms);
}
FishSimulation
void OnEnable()
{
// Find all the schools in the scene
m_Schools = FindObjectsByType<FishSchool>(FindObjectsSortMode.None);
}
void Update()
{
// Ensure Flora is running
if (!FloraSystem.Active)
return;
// Ensure last frames jobs have all finished, and then upload the transforms
foreach (var school in m_Schools)
school.CompleteAndUpload();
// The function that updates each school's array of transforms
float deltaTime = math.min(0.05f, Time.deltaTime);
foreach (var school in m_Schools)
school.Dependency = ScheduleUpdate(deltaTime, school.Settings, school.Transforms);
}
Last updated