说说我理解的ECS

简介: 说说我理解的ECS

在游戏开发中,Entity-Component-System(ECS)是一种架构模式,用于将游戏对象(实体)拆分为组件,并使用系统来处理这些组件的行为和逻辑。让我们更详细地了解每个部分的联系和区别:


1.Entity(实体):


  1. 实体是游戏世界中的基本单位,可以是任何游戏对象,例如玩家、敌人、道具等等。
  2. 一个实体是一个虚拟容器,它本身并不包含任何行为或功能。相反,它由一系列组件构成,用于描述其属性和行为。
  3. 实体通常只有一个唯一的标识符(ID),以便系统可以区分不同的实体。

2.Component(组件):


  1. 组件是实体的一部分,用于描述实体的属性和行为。
  2. 每个组件都有特定的功能,例如位置、渲染、移动、碰撞检测等等。
  3. 组件本身是被动的数据结构,不包含任何行为,它只存储数据。
  4. 实体通过将不同类型的组件组合在一起,来定义其行为和特征。

3.System(系统):


  1. 系统是处理组件的逻辑和行为的实体。
  2. 系统负责执行一系列操作,以更新具有特定组件的实体。
  3. 每个系统通常专注于一个特定的功能,例如移动、渲染、碰撞检测等等。
  4. 系统会从实体中获取所需的组件,并根据组件的数据进行处理。

联系:


  • 实体通过组件来定义其属性和行为,而系统通过操作这些组件来影响实体的行为。
  • 实体和组件之间是多对多的关系,一个实体可以拥有多个不同类型的组件,而一个组件也可以被多个实体共享。
  • 系统可以遍历实体集合,并根据它们的组件来执行相应的行为。

区别:


  • 实体是游戏对象的基本单位,而组件是实体的一部分,用于描述其属性和行为。
  • 组件本身不包含任何行为,只存储数据;而系统负责处理组件的数据并执行相关的行为。
  • 实体在游戏中是动态创建和销毁的,而组件的创建和销毁更加灵活,可以随时添加或移除。
  • 系统通常会关注一类组件的处理,例如一个移动系统会处理所有拥有移动组件的实体,而一个渲染系统会处理所有拥有渲染组件的实体。

总体而言,ECS架构模式的优点在于它提供了一种高度模块化和可扩展的方式来管理游戏对象和行为。通过将游戏对象分解为实体和组件,以及使用系统来处理这些组件,可以更好地管理游戏的复杂性,并实现高性能的游戏系统。


我们来个例子吧,光说理论人头会晕


Entity 实体类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Entity
{
    private Dictionary<Type, object> components = new Dictionary<Type, object>();
    public void Add<T>(T component)
    {
        components[typeof(T)] = component;
    }
    public T Get<T>()
    {
        return (T)components[typeof(T)];
    }
}

提供一个方法,compoent的载入,卸载

Compoent层

using UnityEngine;
public struct PositionComponent
{
    public float X;
    public float Y;
}
public struct MovementComponent
{
    public float Speed;
}
public struct RenderComponent
{
    public string Sprite;
}

System层

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovementSystem
{
    public void Update(Entity entity)
    {
        // 获取实体的组件
        var position = entity.Get<PositionComponent>();
        var movement = entity.Get<MovementComponent>();
        // 处理玩家的输入,并更新位置
        // 这里只是一个示例,实际游戏中需要根据具体输入处理逻辑
        if (Input.GetKey(KeyCode.W))
        {
            position.Y += movement.Speed * Time.deltaTime;
        }
        if (Input.GetKey(KeyCode.S))
        {
            position.Y -= movement.Speed * Time.deltaTime;
        }
        if (Input.GetKey(KeyCode.A))
        {
            position.X -= movement.Speed * Time.deltaTime;
        }
        if (Input.GetKey(KeyCode.D))
        {
            position.X += movement.Speed * Time.deltaTime;
        }
    }
}
public class EnemyMovementSystem
{
    public void Update(Entity entity)
    {
        // 获取实体的组件
        var position = entity.Get<PositionComponent>();
        var movement = entity.Get<MovementComponent>();
        // 简单示例:随机移动敌人
        var randomX = UnityEngine.Random.Range(-1f, 1f);
        var randomY = UnityEngine.Random.Range(-1f, 1f);
        position.X += movement.Speed * randomX * Time.deltaTime;
        position.Y += movement.Speed * randomY * Time.deltaTime;
    }
}

游戏业务层

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameLoop
{
    private List<Entity> entities = new List<Entity>();
    public void AddEntity(Entity entity)
    {
        entities.Add(entity);
    }
    public void Update()
    {
        foreach (var entity in entities)
        {
            if (entity.Has<PlayerMovementSystem>())
            {
                var playerSystem = entity.Get<PlayerMovementSystem>();
                playerSystem.Update(entity);
            }
            else if (entity.Has<EnemyMovementSystem>())
            {
                var enemySystem = entity.Get<EnemyMovementSystem>();
                enemySystem.Update(entity);
            }
        }
        // 渲染实体,这里只是一个示例
        // 实际游戏中可能需要使用更高级的渲染系统
        foreach (var entity in entities)
        {
            var position = entity.Get<PositionComponent>();
            var render = entity.Get<RenderComponent>();
            UnityEngine.Debug.Log($"Rendering entity with sprite: {render.Sprite} at ({position.X}, {position.Y})");
        }
    }
}

好了,我们下面来说说ECS的优缺点


ECS(Entity-Component-System)架构模式在游戏开发中具有许多优点,让我们来看看它的主要优势:


1. **性能优化:** ECS设计的一个主要目标是提高游戏性能。通过将数据与行为分离,ECS允许更好地利用硬件的内存局部性,这可以减少缓存未命中,并提高CPU效率。此外,系统专注于处理特定组件,使得游戏逻辑的更新更加高效。


2. **可扩展性:** ECS可以轻松地适应复杂的游戏系统。添加新的组件和系统不会对现有代码造成影响,因为它们是松耦合的。这使得团队能够更好地协作并且在开发周期中轻松添加新功能。


3. **可维护性:** 由于组件和系统是独立的,不同的开发人员可以专注于不同的部分,使得代码更易于维护。此外,ECS架构的清晰性和模块化使得诊断和解决问题更加容易。


4. **实体组合灵活:** 实体由多个组件组成,使得游戏对象的定义非常灵活。相比传统的继承和组合方式,ECS能够轻松地组合和重组实体的行为和属性,增强了游戏对象的多样性。


5. **逻辑与数据分离:** ECS设计鼓励将数据和行为分离,这有助于代码的可读性和可维护性。开发者可以更容易地专注于游戏的逻辑,而不用担心与数据相关的问题。


6. **跨平台兼容:** 由于ECS关注于数据和逻辑的分离,它可以更容易地适应不同平台和引擎。这使得游戏开发者可以更方便地将游戏移植到不同的平台,而不用担心代码修改的麻烦。


需要注意的是,ECS并不是适合所有类型的游戏。对于小型或简单的项目,引入ECS可能会增加开发复杂性,因此开发者需要根据项目的需求和规模来决定是否使用ECS架构。但对于大型、复杂的游戏项目或对性能要求较高的项目来说,ECS可以成为一个非常有用的开发模式。


总体来说我觉得ecs最大的优势是带来,内存的有序分配,不会形成很多零碎的内存碎片,性能是一个比较重要的指标,还有就是可扩展性,需要用到哪个组件就去加载哪个组件,而不是之前的面向对象的继承,但是这个其实没啥,面向对象也能做到目前,最大的优势还是性能的提高

相关实践学习
通义万相文本绘图与人像美化
本解决方案展示了如何利用自研的通义万相AIGC技术在Web服务中实现先进的图像生成。
7天玩转云服务器
云服务器ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,可降低 IT 成本,提升运维效率。本课程手把手带你了解ECS、掌握基本操作、动手实操快照管理、镜像管理等。了解产品详情:&nbsp;https://www.aliyun.com/product/ecs
相关文章
|
存储 算法 Oracle
极致八股文之JVM垃圾回收器G1&ZGC详解
本文作者分享了一些垃圾回收器的执行过程,希望给大家参考。
|
设计模式 存储 前端开发
MVVM、MVC、MVP三种常见软件架构设计模式的区别
MVC、MVP 和 MVVM 是三种常见的软件架构设计模式,主要通过分离关注点的方式来组织代码结构,优化开发效率。
1739 12
CocosCreator 面试题(十六)Cocos Creator 节点池的基本原理是什么?如何使用?
CocosCreator 面试题(十六)Cocos Creator 节点池的基本原理是什么?如何使用?
1233 0
|
9月前
|
存储 消息中间件 NoSQL
【Redis】常用数据结构之List篇:从常用命令到典型使用场景
本文将系统探讨 Redis List 的核心特性、完整命令体系、底层存储实现以及典型实践场景,为读者构建从理论到应用的完整认知框架,助力开发者在实际业务中高效运用这一数据结构解决问题。
|
12月前
|
NoSQL Redis
跨redis迁移数据的增量迁移方案和工具
面对这个不能完全覆盖的需求,使用RDB备份的需求是无法满足,因为RDB文件会将B的全部数据改为A的数据,显然是不可行的。后来我用了yunedit-redis,这款客户端工具,完美实现了数据的迁移,而且全程都在客户端操作,无需通过编码的方式来实现。
1053 1
|
存储 前端开发 测试技术
MVC、MVP、MVVM 模式
MVC、MVP 和 MVVM 是三种常见的软件架构模式,用于分离用户界面和业务逻辑。MVC(Model-View-Controller)通过模型、视图和控制器分离数据、界面和控制逻辑;MVP(Model-View-Presenter)将控制逻辑移到 Presenter 中,减少视图的负担;MVVM(Model-View-ViewModel)通过数据绑定机制进一步解耦视图和模型,提高代码的可维护性和测试性。
|
设计模式 存储 人工智能
深度解析Unity游戏开发:从零构建可扩展与可维护的游戏架构,让你的游戏项目在模块化设计、脚本对象运用及状态模式处理中焕发新生,实现高效迭代与团队协作的完美平衡之路
【9月更文挑战第1天】游戏开发中的架构设计是项目成功的关键。良好的架构能提升开发效率并确保项目的长期可维护性和可扩展性。在使用Unity引擎时,合理的架构尤为重要。本文探讨了如何在Unity中实现可扩展且易维护的游戏架构,包括模块化设计、使用脚本对象管理数据、应用设计模式(如状态模式)及采用MVC/MVVM架构模式。通过这些方法,可以显著提高开发效率和游戏质量。例如,模块化设计将游戏拆分为独立模块。
1152 3
|
索引
Lua语法(三)——元表与元方法
Lua语法(三)——元表与元方法
404 0
|
弹性计算 图形学
unity ECS简介
unity ECS简介
2143 0
|
网络协议 网络安全 网络虚拟化
网络技术基础(4)——IP地址规划
【2月更文挑战第8天】网络基础笔记