Hi All,
Short Version:
After installing DOTS, I’ve been trying to instantiate 1.000.000 instances and have the unity player stable at 30FPS, but it’s at 0.4FPS
Long Version:
I bet this topic has already been discussed somewhere but after looking for it on the internet I couldn’t find the answers. Nothing better than try it myself then! ![]()
After doing experiments with instantiating prefabs (ECS prefabs) I wonder how would it be even possible to render millions of instances on screen as with 1 million unity struggles. I’m trying to find out how many instances can we handle on screen after optimization (aiming to build a large scale simulation)
Now I reckon that’s a lot more than the old MonoBehaviour could handle but still - during the Unite Austin presentation it’s mentioned that ECS can handle millions of instances on screen, so I’d like to know HOW.
So I created a project, followed the manuals and forums and converted MonoBehaviour prefabs to Entity prefabs - currently using the Hybrid v2 Renderer.
This is what I’ve got:
Little buddy here is the mesh to be rendered - 1.7k tris according to Unity.
Then I wrote the code to convert it to an ECS Entity prefab and instantiated 1.000.000 instances:
Yeah that white plane is actually 1 million instantiated copies of the prefab (it took Unity around 2 minutes to start running). Note the FPS: 0.4 (the editor is open, if I maximize it goes to 0.7FPS :-D)
And this is what happened with the memory:
Then the last thing is what happened to the Systems:
There’s a Hybrid Renderer System that takes 100ms±
I wonder if that’s where the problem is? If it takes 100ms per instance that would indeed kill performance, but not sure what that information means.
Technical Details:
- My machine specs are Ryzen 9 5000 series, RTX 3060, 32GB (Alienware R15 M5)
- There are no Systems running that would impact performance (as seen on the run times above)
- Bellow the code used to convert the prefab and instantiate things:
//PrefabConverterDeclare.cs
using Unity.Burst;
using Unity.Collections;
using Unity.Entities;
using Unity.Jobs;
using Unity.Mathematics;
using Unity.Transforms;
[UpdateInGroup(typeof(GameObjectDeclareReferencedObjectsGroup))]
class PrefabConverterDeclare : GameObjectConversionSystem
{
protected override void OnUpdate()
{
Entities.ForEach((Knight prefabReference) =>
{
DeclareReferencedPrefab(prefabReference.Prefab);
});
}
}
// EntitySpawnerSystem.cs
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;
using UnityEngine;
using Random = Unity.Mathematics.Random;
public class EntitySpawnerSystem : ComponentSystem
{
private Random random;
protected override void OnStartRunning()
{
random = new Random(56);
Entities.ForEach((ref KnightPrefabComponent component) =>
{
var entities = EntityManager.Instantiate(component.prefabEntity, component.totalOfInstances, Unity.Collections.Allocator.Temp);
foreach (var entity in entities)
{
EntityManager.SetComponentData(entity, new Translation()
{
Value = new float3(random.NextFloat(0, 200), 0, random.NextFloat(0, 200))
});
}
});
}
protected override void OnUpdate()
{
}
}
// KnightPrefabComponent.cs
using Unity.Entities;
public struct KnightPrefabComponent : IComponentData
{
public Entity prefabEntity;
public int totalOfInstances;
}
// Knight.cs
using System.Collections;
using System.Collections.Generic;
using Unity.Entities;
using UnityEngine;
public class Knight : MonoBehaviour, IConvertGameObjectToEntity
{
public GameObject Prefab;
public int totalOfInstances;
public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
{
var prefab = conversionSystem.GetPrimaryEntity(Prefab);
var component = new KnightPrefabComponent { prefabEntity = prefab, totalOfInstances = totalOfInstances };
dstManager.AddComponentData(entity, component);
}
}





