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

相关实践学习
借助OSS搭建在线教育视频课程分享网站
本教程介绍如何基于云服务器ECS和对象存储OSS,搭建一个在线教育视频课程分享网站。
7天玩转云服务器
云服务器ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,可降低 IT 成本,提升运维效率。本课程手把手带你了解ECS、掌握基本操作、动手实操快照管理、镜像管理等。了解产品详情:&nbsp;https://www.aliyun.com/product/ecs
相关文章
|
缓存 图形学
游戏通用解决方案之红点设计
游戏通用解决方案之红点设计
481 0
cocoscreator实现spine用外部图片进行换皮
cocoscreator实现spine用外部图片进行换皮
407 0
|
5月前
|
IDE API 开发工具
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之XComponent组件
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之XComponent组件
289 2
|
NoSQL MongoDB 索引
Mongo优化——explain函数的基本使用
当数据量不大时,查询语句随便写,只要实现逻辑功能即可;但当数据量大到一定程度时,可能以前的方法就不可行了,因为一是查询数度变慢,更有甚者可能因数据量大而导致查询失败。解决这种问题最简单的方法是添加索引并利用好这些索引。可以通过explain函数来分析:1、在建索引前数据请求情况2、创建索引后数据请求是否有变好。现在就来看看explain相关知识。
4003 0
|
开发者
如何设计一套好的技能buff(二)
如何设计一套好的技能buff(二)
202 0
|
弹性计算 数据库
ECS使用有感
我是一名即将步入社会的大学生,随着网络法等相关专业知识的学习愈发强烈。查询资料时,常常会浏览到制作精美的个人站,因此产生了建设自己个人站的设想,但是由于业余时间少之甚少,同时听闻购买域名与服务器的价格不菲,因此计划一直未能实现
|
12月前
|
算法 安全 Go
Go切片删除元素错过这篇你就out了
Go切片删除元素错过这篇你就out了
2269 0
|
弹性计算 监控 JavaScript
ECS
体验感受
147 0
|
弹性计算 应用服务中间件 nginx
ECS使用分享
关于飞天加速计划的学生活动ECS
151 0
|
弹性计算 Java Linux
ECS心得
ECS心得
325 1