
Fish
The fish sample scene shows off a modified version of Unity's ECS BoidSample, and showcases how to create thousands of instances, update them and sync the changes to Flora.
Additionally, each instance is culled performantly and with correct motion vectors.

The important areas of the sample are in two 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