we used DOTS and entities to simulate loads of fish for our coral reef city builder
by u/dalmins in Unity3D
public struct Boid : IComponentData
{
public float MovementSpeed;
public float TurnSpeed;
public float Size;
public float4 Velocity;
public float4 AngularVelocity;
public BoidType Type;
}
public partial struct SeparationJob : IJobEntity
{
[WriteOnly] public NativeArray<float4> Separation;
[ReadOnly] public NativeParallelMultiHashMap<int2, Entity> BoidCells;
[ReadOnly] public ComponentLookup<LocalTransform> TransformLookup;
public float AvoidFactor;
public void Execute(Entity e, int index, in LocalTransform transform, in Boid boid)
{
var delta = float4.zero;
var key = (int3)(transform.Position * ChunkSize);
key.y = 0;
var neighbors = BoidCells.GetValuesForKey(key.xz);
while (neighbors.MoveNext())
{
if (neighbors.Current.Equals(e)) continue;
var other = TransformLookup[neighbors.Current];
if (math.distancesq(transform.Position, other.Position) < boid.Size * boid.Size)
{
delta += transform.Position.xyzz - other.Position.xyzz;
}
}
Separation[index] = delta * AvoidFactor;
}
}
public partial struct MoveJob : IJobEntity
{
[ReadOnly] public NativeArray<float4> Separation;
[ReadOnly] public NativeArray<float4> Alignment;
[ReadOnly] public NativeArray<float4> Cohesion;
public float DeltaTime;
public void Execute(ref LocalTransform transform, ref Boid boid)
{
var velocity =
boid.Velocity +
(Separation[index] + Alignment[index] + Cohesion[index]) * DeltaTime;
boid.Velocity = velocity;
transform.Position += boid.Velocity.xyz * DeltaTime;
}
}
Shaders, tools, animation, math, and more, the new "Unity Dev Bundle" is still available for a bit longer. 🔥 Get it here: https://t.co/gPPcuZDuFX#unity3d #gamedev pic.twitter.com/mnxRUCtUHC
— Jettelly Inc. (@jettelly) April 8, 2026