Unity3D中的ECS(Entity-Component-System)架构简介

核心概念
  • Entity(实体):轻量级的唯一标识符,不包含任何数据或逻辑。类似于传统Unity中的GameObject,但更轻量化。
  • Component(组件):纯数据容器,不包含逻辑(如位置、速度等)。类似于传统Unity中的Component,但仅存储数据。
  • System(系统):处理所有逻辑,操作符合特定条件(即具有某些组件组合)的实体。例如,移动系统会处理所有包含位置和速度组件的实体。
ECS的优势
  • 性能优化:通过连续的数据存储提高缓存命中率。
  • 多线程友好:系统逻辑可以并行化(借助Unity的Job System和Burst编译器)。
  • 模块化:逻辑与数据分离,便于维护代码。
具体示例:旋转立方体
  1. 定义 Component(数据)

    using Unity.Entities;
    
    // 旋转速度组件
    public struct RotationSpeed : IComponentData
    {
        public float Value; // 每秒旋转的角度(单位:度)
    }
    
    // 当前旋转角度组件
    public struct RotationAngle : IComponentData
    {
        public float Value; // 当前旋转角度
    }
    
  2. 创建 System(逻辑)

    using Unity.Entities;
    using Unity.Burst;
    using Unity.Mathematics;
    
    [BurstCompile] // 启用 Burst 编译器优化
    public partial struct RotateCubeSystem : ISystem
    {
        [BurstCompile]
        public void OnUpdate(ref SystemState state)
        {
            float deltaTime = SystemAPI.Time.DeltaTime;
    
            foreach (var (speed, angle) in 
                     SystemAPI.Query<RefRO<RotationSpeed>, RefRW<RotationAngle>>())
            {
                // 更新旋转角度
                angle.ValueRW.Value += speed.ValueRO.Value * deltaTime;
            }
        }
    }
    
  3. 生成 Entity 并添加 Component

    using Unity.Entities;
    using Unity.Mathematics;
    using UnityEngine;
    
    public class CubeSpawner : MonoBehaviour
    {
        public int cubeCount = 10000;
        public GameObject cubePrefab;
    
        void Start()
        {
            var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
    
            var settings = GameObjectConversionSettings.FromWorld(
                World.DefaultGameObjectInjectionWorld, 
                new BlobAssetStore()
            );
            var cubeEntityPrefab = GameObjectConversionUtility.ConvertGameObjectHierarchy(
                cubePrefab, 
                settings
            );
    
            for (int i = 0; i < cubeCount; i++)
            {
                var entity = entityManager.Instantiate(cubeEntityPrefab);
                
                entityManager.AddComponentData(entity, new RotationSpeed
                {
                    Value = UnityEngine.Random.Range(10f, 100f) // 随机旋转速度
                });
                
                entityManager.AddComponentData(entity, new RotationAngle
                {
                    Value = 0f // 初始角度
                });
            }
        }
    }
    
  4. 渲染旋转效果
    在Shader或MonoBehaviour中读取RotationAngle的值,并应用到立方体的Transform上。

与传统 Unity 对比
  • 传统方式:每个立方体作为一个GameObject,挂载MonoBehaviour脚本,性能开销大(例如10,000个Update调用)。
  • ECS方式:数据连续存储,逻辑批量处理,通过Burst编译和多线程优化,性能提升显著。
适用场景
  • 大规模对象处理(如粒子系统、大规模战斗等)。
  • 需要多线程计算的复杂逻辑(如物理模拟、AI决策)。
  • 对性能敏感的项目(如移动端或VR/AR应用)。
注意事项
  • 使用ECS需要安装Entities包(可通过Unity Package Manager安装)。
  • 可以通过Hybrid ECS(如使用ConvertToEntity组件)实现与GameObject的混合使用。
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐