Примеры кода

Основы Entity Component System (ECS)

Создание сущностей, компонентов и систем для высокопроизводительной архитектуры.

using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;
using UnityEngine;

// Компонент для движения
public struct MovementComponent : IComponentData
{
    public float3 velocity;
    public float speed;
}

// Система движения
[UpdateInGroup(typeof(SimulationSystemGroup))]
public partial class MovementSystem : SystemBase
{
    protected override void OnUpdate()
    {
        float deltaTime = Time.DeltaTime;
        
        Entities
            .WithAll<MovementComponent>()
            .ForEach((ref Translation translation, in MovementComponent movement) =>
            {
                translation.Value += movement.velocity * movement.speed * deltaTime;
                
                // Ограничение области движения
                if (math.abs(translation.Value.x) > 50f)
                    translation.Value.x = -translation.Value.x;
                if (math.abs(translation.Value.z) > 50f)
                    translation.Value.z = -translation.Value.z;
                    
            }).ScheduleParallel();
    }
}

// MonoBehaviour для создания сущностей
public class EntitySpawner : MonoBehaviour
{
    public GameObject prefab;
    public int spawnCount = 1000;
    
    void Start()
    {
        var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
        var settings = GameObjectConversionSettings.FromWorld(
            World.DefaultGameObjectInjectionWorld, null);
        var prefabEntity = GameObjectConversionUtility.ConvertGameObjectHierarchy(
            prefab, settings);
            
        Debug.Log($"Создание {spawnCount} сущностей с ECS");
        
        for (int i = 0; i < spawnCount; i++)
        {
            var entity = entityManager.Instantiate(prefabEntity);
            
            entityManager.AddComponentData(entity, new MovementComponent
            {
                velocity = new float3(
                    UnityEngine.Random.Range(-1f, 1f),
                    0,
                    UnityEngine.Random.Range(-1f, 1f)
                ),
                speed = UnityEngine.Random.Range(5f, 15f)
            });
        }
        
        Debug.Log("ECS сущности созданы успешно");
    }
}
                            

Jobs System для параллельных вычислений

Использование Jobs System для эффективной обработки больших объемов данных.

using Unity.Collections;
using Unity.Jobs;
using Unity.Mathematics;
using UnityEngine;

// Job для обработки позиций частиц
public struct ParticleUpdateJob : IJobParallelFor
{
    public NativeArray<float3> positions;
    public NativeArray<float3> velocities;
    [ReadOnly] public float deltaTime;
    [ReadOnly] public float3 gravity;
    
    public void Execute(int index)
    {
        velocities[index] += gravity * deltaTime;
        positions[index] += velocities[index] * deltaTime;
        
        // Отскок от земли
        if (positions[index].y < 0)
        {
            positions[index] = new float3(positions[index].x, 0, positions[index].z);
            velocities[index] = new float3(
                velocities[index].x * 0.8f,
                -velocities[index].y * 0.8f,
                velocities[index].z * 0.8f
            );
        }
    }
}

// Менеджер системы частиц
public class ParticleSystemManager : MonoBehaviour
{
    public int particleCount = 10000;
    public GameObject particlePrefab;
    
    private NativeArray<float3> positions;
    private NativeArray<float3> velocities;
    private Transform[] particleTransforms;
    private JobHandle jobHandle;
    
    void Start()
    {
        InitializeParticles();
        Debug.Log($"Инициализирована система частиц с {particleCount} частицами");
    }
    
    void InitializeParticles()
    {
        positions = new NativeArray<float3>(particleCount, Allocator.Persistent);
        velocities = new NativeArray<float3>(particleCount, Allocator.Persistent);
        particleTransforms = new Transform[particleCount];
        
        for (int i = 0; i < particleCount; i++)
        {
            var particle = Instantiate(particlePrefab);
            particleTransforms[i] = particle.transform;
            
            positions[i] = new float3(
                UnityEngine.Random.Range(-25f, 25f),
                UnityEngine.Random.Range(10f, 50f),
                UnityEngine.Random.Range(-25f, 25f)
            );
            
            velocities[i] = new float3(
                UnityEngine.Random.Range(-10f, 10f),
                0,
                UnityEngine.Random.Range(-10f, 10f)
            );
        }
    }
    
    void Update()
    {
        jobHandle.Complete();
        
        var particleJob = new ParticleUpdateJob
        {
            positions = positions,
            velocities = velocities,
            deltaTime = Time.deltaTime,
            gravity = new float3(0, -9.81f, 0)
        };
        
        jobHandle = particleJob.Schedule(particleCount, 64);
        jobHandle.Complete();
        
        // Обновление Transform компонентов
        for (int i = 0; i < particleCount; i++)
        {
            if (particleTransforms[i] != null)
            {
                particleTransforms[i].position = positions[i];
            }
        }
    }
    
    void OnDestroy()
    {
        jobHandle.Complete();
        if (positions.IsCreated) positions.Dispose();
        if (velocities.IsCreated) velocities.Dispose();
    }
}
                        

Burst Compiler для максимальной производительности

Использование Burst Compiler для компиляции высокопроизводительного кода.

using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;
using Unity.Mathematics;
using UnityEngine;

// Burst-компилированный job
[BurstCompile]
public struct MathIntensiveJob : IJobParallelFor
{
    [ReadOnly] public NativeArray<float3> inputPositions;
    public NativeArray<float3> outputPositions;
    [ReadOnly] public float time;
    [ReadOnly] public float frequency;
    [ReadOnly] public float amplitude;
    
    public void Execute(int index)
    {
        float3 pos = inputPositions[index];
        
        // Сложные математические вычисления
        float wave1 = math.sin(pos.x * frequency + time) * amplitude;
        float wave2 = math.cos(pos.z * frequency + time) * amplitude;
        float height = wave1 + wave2;
        
        outputPositions[index] = new float3(pos.x, height, pos.z);
    }
}

// Менеджер с Burst-оптимизацией
public class BurstOptimizedManager : MonoBehaviour
{
    public int objectCount = 50000;
    public GameObject objectPrefab;
    public float waveFrequency = 0.5f;
    public float waveAmplitude = 5f;
    
    private NativeArray<float3> originalPositions;
    private NativeArray<float3> currentPositions;
    private Transform[] objectTransforms;
    private JobHandle jobHandle;
    
    void Start()
    {
        InitializeSimulation();
        Debug.Log($"Burst-оптимизированная симуляция с {objectCount} объектами");
    }
    
    void InitializeSimulation()
    {
        originalPositions = new NativeArray<float3>(objectCount, Allocator.Persistent);
        currentPositions = new NativeArray<float3>(objectCount, Allocator.Persistent);
        objectTransforms = new Transform[objectCount];
        
        int gridSize = Mathf.CeilToInt(Mathf.Sqrt(objectCount));
        
        for (int i = 0; i < objectCount; i++)
        {
            int x = i % gridSize;
            int z = i / gridSize;
            
            float3 position = new float3(x * 2f - gridSize, 0, z * 2f - gridSize);
            originalPositions[i] = position;
            
            var obj = Instantiate(objectPrefab);
            objectTransforms[i] = obj.transform;
        }
    }
    
    void Update()
    {
        jobHandle.Complete();
        
        var mathJob = new MathIntensiveJob
        {
            inputPositions = originalPositions,
            outputPositions = currentPositions,
            time = Time.time,
            frequency = waveFrequency,
            amplitude = waveAmplitude
        };
        
        jobHandle = mathJob.Schedule(objectCount, 128);
        jobHandle.Complete();
        
        // Обновление Transform компонентов
        for (int i = 0; i < objectCount; i++)
        {
            if (objectTransforms[i] != null)
            {
                objectTransforms[i].position = currentPositions[i];
            }
        }
    }
    
    void OnDestroy()
    {
        jobHandle.Complete();
        if (originalPositions.IsCreated) originalPositions.Dispose();
        if (currentPositions.IsCreated) currentPositions.Dispose();
    }
}
                        

Оптимизация производительности

Продвинутые техники оптимизации для максимальной производительности.

using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;
using UnityEngine;

// Компонент для LOD системы
public struct LODComponent : IComponentData
{
    public float distance;
    public int lodLevel;
    public bool isVisible;
}

// Система LOD
[UpdateInGroup(typeof(SimulationSystemGroup))]
public partial class LODSystem : SystemBase
{
    protected override void OnUpdate()
    {
        float3 cameraPosition = Camera.main.transform.position;
        
        Entities
            .WithAll<LODComponent>()
            .ForEach((ref LODComponent lod, in Translation translation) =>
            {
                float distance = math.distance(translation.Value, cameraPosition);
                lod.distance = distance;
                
                if (distance < 10f)
                {
                    lod.lodLevel = 0; // Высокая детализация
                    lod.isVisible = true;
                }
                else if (distance < 50f)
                {
                    lod.lodLevel = 1; // Средняя детализация
                    lod.isVisible = true;
                }
                else
                {
                    lod.isVisible = false; // Не отображать
                }
                
            }).ScheduleParallel();
    }
}

// Менеджер производительности
public class PerformanceManager : MonoBehaviour
{
    public int targetFPS = 60;
    public float cullingDistance = 200f;
    
    private float frameTime;
    
    void Update()
    {
        frameTime = Time.deltaTime;
        float currentFPS = 1f / frameTime;
        
        // Адаптивная оптимизация
        if (currentFPS < targetFPS * 0.8f)
        {
            ReduceQuality();
        }
        else if (currentFPS > targetFPS * 1.2f)
        {
            IncreaseQuality();
        }
        
        if (Time.frameCount % 60 == 0)
        {
            Debug.Log($"FPS: {currentFPS:F1}");
        }
    }
    
    void ReduceQuality()
    {
        cullingDistance = math.max(50f, cullingDistance * 0.9f);
        Debug.Log("Качество снижено для улучшения производительности");
    }
    
    void IncreaseQuality()
    {
        cullingDistance = math.min(200f, cullingDistance * 1.05f);
        Debug.Log("Качество повышено");
    }
}
                        

Массовая симуляция с тысячами объектов

Создание масштабируемых симуляций с большим количеством объектов.

using Unity.Entities;
using Unity.Collections;
using Unity.Mathematics;
using Unity.Transforms;
using UnityEngine;

// Компонент для роя
public struct SwarmComponent : IComponentData
{
    public float3 target;
    public float speed;
    public float separationRadius;
}

// Система роя (Boids)
[UpdateInGroup(typeof(SimulationSystemGroup))]
public partial class SwarmSystem : SystemBase
{
    protected override void OnUpdate()
    {
        float deltaTime = Time.DeltaTime;
        
        Entities
            .ForEach((ref Translation translation, in SwarmComponent swarm) =>
            {
                // Движение к цели
                float3 toTarget = math.normalize(swarm.target - translation.Value);
                translation.Value += toTarget * swarm.speed * deltaTime;
                
            }).ScheduleParallel();
    }
}

// Массовый симулятор
public class MassiveSimulation : MonoBehaviour
{
    public GameObject entityPrefab;
    public int entityCount = 50000;
    public float spawnRadius = 100f;
    
    private EntityManager entityManager;
    
    void Start()
    {
        InitializeMassiveSimulation();
        Debug.Log($"Массовая симуляция с {entityCount} объектами");
    }
    
    void InitializeMassiveSimulation()
    {
        entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
        
        var settings = GameObjectConversionSettings.FromWorld(
            World.DefaultGameObjectInjectionWorld, null);
        var prefabEntity = GameObjectConversionUtility.ConvertGameObjectHierarchy(
            entityPrefab, settings);
        
        var entities = new NativeArray<Entity>(entityCount, Allocator.Temp);
        entityManager.Instantiate(prefabEntity, entities);
        
        for (int i = 0; i < entityCount; i++)
        {
            var entity = entities[i];
            
            float3 randomPos = UnityEngine.Random.insideUnitSphere * spawnRadius;
            randomPos.y = math.abs(randomPos.y);
            
            entityManager.SetComponentData(entity, new Translation
            {
                Value = randomPos
            });
            
            entityManager.AddComponentData(entity, new SwarmComponent
            {
                target = float3.zero,
                speed = UnityEngine.Random.Range(5f, 15f),
                separationRadius = 2f
            });
        }
        
        entities.Dispose();
    }
    
    void Update()
    {
        // Обновление цели на основе позиции мыши
        if (Input.GetMouseButton(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            if (Physics.Raycast(ray, out RaycastHit hit))
            {
                UpdateSwarmTarget(hit.point);
            }
        }
    }
    
    void UpdateSwarmTarget(float3 newTarget)
    {
        Entities
            .WithAll<SwarmComponent>()
            .ForEach((ref SwarmComponent swarm) =>
            {
                swarm.target = newTarget;
            }).Run();
    }
}