I followed this tutorial Getting Started with ECS in Unity 2019 and he was able to easily get 100,000 sprites on the screen, I can’t get more than 30,000, which is more than with the classical system but not nearly the gain I was supposed to get.
So I was just wondering what were some of the common reasons it might be slower than it should? I have burst compiler enabled, and my profiler looks like this
Everything is the same as the guy’s tutorial so has DOTS just gotten slower in the year and a half since the video? Here is how to recreate my project, unzip this package [174299-dots-test-assets.zip|174299] and import it into a 2D scene. You have to have the entities package installed, and the hybrid renderer. Then, make an empty object and put the testing script on it. Select the quad for the mesh and the weird animal sprite material for the material. Then just click play. The amount of objects you spawn is in the testing script. Again, I can only get 30,000 above 30fps, everyone else can get like 100,000 sometimes 200,000. I tried it on my laptop which has a newer i7 in it to see if it would make a difference and it ran worse I guess because it doesn’t have a gpu. Thanks for any help!
(1). Enable GPU Instancing in shader to cut on those render batches.
100 or 3k render batches is fine. 30000 render batches will convert most computers into a stove.
_
(2). Optimize your code
using UnityEngine;
using Unity.Entities;
using Unity.Transforms;
using Unity.Rendering;
using Unity.Mathematics;
// FYI: starting class names with lowe-case letters is criminal...
public class testing : MonoBehaviour
{
[SerializeField] Mesh _mesh;
[SerializeField] Material _material;
[SerializeField] int _amount = 30000;
private void Start ()
{
EntityManager entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
EntityArchetype entityArchetype = entityManager.CreateArchetype(
// prefabs aren't visible nor active
// var instance = entityManager.Instantiate( prefab ); - removes this tag for instances
typeof(Prefab) ,
// typeof(Translation) // local position needs to be converted to LocalToWorld every sim frame so lets get rid of it
typeof(LocalToWorld) ,// transform
typeof(RenderMesh) ,
ComponentType.ChunkComponent<RenderBounds>() ,
typeof(WorldRenderBounds) ,
ComponentType.ChunkComponent<ChunkWorldRenderBounds>() ,
typeof(MoveSpeedComponent)
);
var prefab = entityManager.CreateEntity( entityArchetype );
{
entityManager.SetSharedComponentData( prefab , new RenderMesh{
mesh = _mesh,
material = _material
} );
}
RenderBounds renderBounds = new RenderBounds{ Value = _mesh.bounds.ToAABB() };
var random = new Unity.Mathematics.Random( seed: (uint) System.DateTime.Now.GetHashCode() );
for( int i=0 ; i<_amount ; i++ )
{
Entity entity = entityManager.Instantiate( prefab );
var chunk = entityManager.GetChunk( entity );
entityManager.SetChunkComponentData<RenderBounds>( chunk , renderBounds );
float3 pos = new float3{ x=random.NextFloat(-5f,5f) , y=random.NextFloat(-5f,5f) , z=0f };
quaternion rot = quaternion.identity;
float3 scale = new float3{ x=1 , y=1 , z=1 };
entityManager.SetComponentData( entity , new LocalToWorld{
Value = float4x4.TRS( pos , rot , scale )
} );
entityManager.SetComponentData( entity , new MoveSpeedComponent{
moveSpeed = random.NextFloat(1f,2f) ,
up = true
} );
}
}
}
_
Your MoverSystem
was not multi-threaded nor burst-compiled, a fix:
using Unity.Mathematics;
using Unity.Entities;
using Unity.Transforms;
public class MoverSystem : SystemBase
{
protected override void OnUpdate ()
{
float dt = Time.DeltaTime;
Entities
.WithName("translation_job")
.ForEach( ( ref LocalToWorld transform , ref MoveSpeedComponent moveSpeedC ) =>
{
float3 position = transform.Position;
position.y += moveSpeedC.moveSpeed * dt;
if( position.y>5 && moveSpeedC.up )
{
moveSpeedC.moveSpeed *= -1f;
moveSpeedC.up = false;
}
else if( position.y<-5 && !moveSpeedC.up )
{
moveSpeedC.moveSpeed *= -1f;
moveSpeedC.up = true;
}
moveSpeedC.level += 1f * dt;
transform.Value = float4x4.Translate( position );//float4x4.TRS( pos , rot , scale )
})
.WithBurst().ScheduleParallel();
}
}