✅ Unity ECS & Jobs System: революция производительности
Что это?
Архитектура, где данные хранятся отдельно от логики (Data-Oriented Design). Позволяет обрабатывать десятки тысяч объектов без падения FPS.
Зачем?
- Массовые симуляции (орды врагов, частицы, песочницы)
- Полное использование многоядерных процессоров
- Предсказуемое управление памятью (Zero GC Allocations)
Базовые понятия:
- Entity — не объект, а легковесный ID.
- ComponentData — чистые данные (struct, без методов).
- System — логика, которая работает с массивами компонентов.
Пример (спавн кубов):
Важно!
- Требуется пакет
- Это полный разрыв с
- Идеально для VR/AR с strict performance требованиями
💡 Начинай с гибридного подхода:
#Unity #ECS #Performance #Optimization #JobSystem
Что это?
Архитектура, где данные хранятся отдельно от логики (Data-Oriented Design). Позволяет обрабатывать десятки тысяч объектов без падения FPS.
Зачем?
- Массовые симуляции (орды врагов, частицы, песочницы)
- Полное использование многоядерных процессоров
- Предсказуемое управление памятью (Zero GC Allocations)
Базовые понятия:
- Entity — не объект, а легковесный ID.
- ComponentData — чистые данные (struct, без методов).
- System — логика, которая работает с массивами компонентов.
Пример (спавн кубов):
// Компонент (данные)
public struct RotationSpeed : IComponentData
{
public float RadiansPerSecond;
}
// Система (логика)
public class RotationSystem : SystemBase
{
protected override void OnUpdate()
{
float deltaTime = Time.DeltaTime;
Entities
.ForEach((ref Rotatable rotatable, in RotationSpeed speed) =>
{
rotatable.Value = math.mul(
math.normalize(rotatable.Value),
quaternion.AxisAngle(math.up(), speed.RadiansPerSecond * deltaTime)
);
}).ScheduleParallel();
}
}
Важно!
- Требуется пакет
Entities и Unity.Burst- Это полный разрыв с
MonoBehaviour и ООП- Идеально для VR/AR с strict performance требованиями
💡 Начинай с гибридного подхода:
MonoBehaviour -> преобразование в Entity через ConvertToEntity.#Unity #ECS #Performance #Optimization #JobSystem
🔥3
✅ Unity ECS на практике: Пишем первую систему
Следующий шаг
Разберем, как преобразовать обычные GameObject в Entity и работать с ними.
1. Гибридный подход (MonoBehaviour -> Entity)
- Добавь на GameObject компонент ConvertToEntity
- Он автоматически преобразует объект и его дочерние элементы при старте
2. Authoring (Создание данных в редакторе)
Пишем MonoBehaviour-обертку для визуальной настройки.
3. Система с зависимостями
Системы могут требовать наличие других компонентов.
4. Важные нюансы:
- RefRO - Read Only доступ (только чтение)
- RefRW - Read Write доступ (чтение и запись)
- Используй SystemAPI.Query для итерации по сущностям с нужными компонентами
- Все изменения автоматически параллелятся Burst компил💡 Совет: Начинай с малого — перенеси в ECS самые тяжелые части (частицы, ИИ). Не нужно переписывать всё сразу.
#Unity #ECS #DOTS #Performance #Burst
Следующий шаг
Разберем, как преобразовать обычные GameObject в Entity и работать с ними.
1. Гибридный подход (MonoBehaviour -> Entity)
- Добавь на GameObject компонент ConvertToEntity
- Он автоматически преобразует объект и его дочерние элементы при старте
2. Authoring (Создание данных в редакторе)
Пишем MonoBehaviour-обертку для визуальной настройки.
public class RotationSpeedAuthoring : MonoBehaviour
{
public float DegreesPerSecond = 360f;
}
// "Повар" преобразует Authoring в ComponentData
public class RotationSpeedAuthoringBaker : Baker<RotationSpeedAuthoring>
{
public override void Bake(RotationSpeedAuthoring authoring)
{
var entity = GetEntity(TransformUsageFlags.Dynamic);
AddComponent(entity, new RotationSpeed
{
RadiansPerSecond = math.radians(authoring.DegreesPerSecond)
});
}
}
3. Система с зависимостями
Системы могут требовать наличие других компонентов.
// Система, которая работает только с объектами, у которых есть RotationSpeed и Rotation
[UpdateInGroup(typeof(SimulationSystemGroup))]
public partial struct MyRotationSystem : ISystem
{
public void OnUpdate(ref SystemState state)
{
foreach (var (transform, speed) in
SystemAPI.Query<RefRW<LocalTransform>, RefRO<RotationSpeed>>())
{
transform.ValueRW = transform.ValueRO.RotateY(
speed.ValueRO.RadiansPerSecond * SystemAPI.Time.DeltaTime
);
}
}
}
4. Важные нюансы:
- RefRO - Read Only доступ (только чтение)
- RefRW - Read Write доступ (чтение и запись)
- Используй SystemAPI.Query для итерации по сущностям с нужными компонентами
- Все изменения автоматически параллелятся Burst компил💡 Совет: Начинай с малого — перенеси в ECS самые тяжелые части (частицы, ИИ). Не нужно переписывать всё сразу.
#Unity #ECS #DOTS #Performance #Burst
🔥5 1
⚡️ Unity: C# Data-Oriented Design для максимальной производительности
Устал от медленного foreach по тысячам объектов? Struct of Arrays — это подход, который ускоряет обработку данных, как в настоящем ECS.
❌ Проблема стандартного подхода:
• Кэш-промахи процессора
• Разбросанные в памяти объекты
• Виртуальные вызовы
✅ Решение: Struct of Arrays (основа ECS)
1️⃣ Правильная структура данных:
Данные хранятся в плотных массивах — процессор обрабатывает их последовательно, без промахов кэша.
2️⃣ Оптимизированная итерация:
• Нет виртуальных вызовов
• Данные последовательны в кэше
• Автоматическая векторизация
• Параллелизация
💡 Реальный результат:
Обработка 10 000 юнитов ускоряется в 2-5 раз по сравнению с GameObject/GetComponent в цикле. Даже против готового списка MonoBehaviour выигрыш за счет кэш-дружественности.
🚀 Следующий уровень:
Unity.Entities (DOTS) — автоматическое управление чанками, параллельная обработка и Burst компиляция.
💬 Используешь плотные массивы для данных? Делитесь опытом в комментариях!
🔔 Подпишись — больше фишек для инди-оптимизации впереди.
👉Akrus Games | Unity
#Unity3D #UnityOptimization #ECS #DOTS #CSharp
Устал от медленного foreach по тысячам объектов? Struct of Arrays — это подход, который ускоряет обработку данных, как в настоящем ECS.
❌ Проблема стандартного подхода:
foreach (var enemy in enemies) {
enemy.Update(); // Кэш-промахи, разбросанные объекты в памяти
}• Кэш-промахи процессора
• Разбросанные в памяти объекты
• Виртуальные вызовы
✅ Решение: Struct of Arrays (основа ECS)
1️⃣ Правильная структура данных:
public struct EnemyChunk {
public Vector3[] positions;
public float[] healths;
public int count;
}Данные хранятся в плотных массивах — процессор обрабатывает их последовательно, без промахов кэша.
2️⃣ Оптимизированная итерация:
for (int i = 0; i < chunk.count; i++) {
chunk.positions[i] += Vector3.forward * speed;
chunk.healths[i] -= Time.deltaTime;
}• Нет виртуальных вызовов
• Данные последовательны в кэше
• Автоматическая векторизация
• Параллелизация
💡 Реальный результат:
Обработка 10 000 юнитов ускоряется в 2-5 раз по сравнению с GameObject/GetComponent в цикле. Даже против готового списка MonoBehaviour выигрыш за счет кэш-дружественности.
🚀 Следующий уровень:
Unity.Entities (DOTS) — автоматическое управление чанками, параллельная обработка и Burst компиляция.
💬 Используешь плотные массивы для данных? Делитесь опытом в комментариях!
🔔 Подпишись — больше фишек для инди-оптимизации впереди.
👉Akrus Games | Unity
#Unity3D #UnityOptimization #ECS #DOTS #CSharp
❤7 1