说说我理解的ECS

本文涉及的产品
云服务器 ECS,每月免费额度200元 3个月
云服务器ECS,u1 2核4GB 1个月
简介: 说说我理解的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最大的优势是带来,内存的有序分配,不会形成很多零碎的内存碎片,性能是一个比较重要的指标,还有就是可扩展性,需要用到哪个组件就去加载哪个组件,而不是之前的面向对象的继承,但是这个其实没啥,面向对象也能做到目前,最大的优势还是性能的提高

相关实践学习
一小时快速掌握 SQL 语法
本实验带您学习SQL的基础语法,快速入门SQL。
7天玩转云服务器
云服务器ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,可降低 IT 成本,提升运维效率。本课程手把手带你了解ECS、掌握基本操作、动手实操快照管理、镜像管理等。了解产品详情:&nbsp;https://www.aliyun.com/product/ecs
相关文章
|
9月前
|
缓存 图形学
游戏通用解决方案之红点设计
游戏通用解决方案之红点设计
261 0
|
存储 人工智能 城市大脑
ECS
阿里云 概念 阿里云创立于2009年,是全球领先的云计算及人工智能科技公司,致力于以在线公共服务的方式,提供安全、可靠的计算和数据处理能力,让计算和人工智能成为普惠科技。阿里云服务着制造、金融、政务、交通、医疗、电信、能源等众多领域的领军企业,包括中国联通、12306、中石化、中石油、飞利浦、华大基因等大型企业客户,以及微博、知乎、锤子科技等明星互联网公司。在天猫双11全球狂欢节、12306春运购票等极富挑战的应用场景中,阿里云保持着良好的运行纪录。
128 0
|
弹性计算 数据库
ECS使用有感
我是一名即将步入社会的大学生,随着网络法等相关专业知识的学习愈发强烈。查询资料时,常常会浏览到制作精美的个人站,因此产生了建设自己个人站的设想,但是由于业余时间少之甚少,同时听闻购买域名与服务器的价格不菲,因此计划一直未能实现
|
弹性计算 Linux 云计算
玩转ECS
很高兴在这里发表一篇文章来跟大家分享我最近使用ECS的体验感受。
140 0
|
弹性计算 小程序 Linux
使用Ecs的心得
Ecs 可以做什么 如何更好地使用Ecs
|
弹性计算 NoSQL 安全
关于ecs使用的一点心得
记录一下怎么使用ecs的
|
弹性计算 JavaScript 前端开发
使用ECS有感
通过ECS搭建的环境 让我跑起来了原来跑不动的微服务项目。
115 0
使用ECS有感
|
弹性计算 Apache 数据库
第一次使用ECS
通过参加“飞天加速计划-高校学生在家实践”活动,学习使用阿里云服务器ECS
243 3
第一次使用ECS
|
9月前
|
弹性计算 图形学
unity ECS简介
unity ECS简介
709 0
|
弹性计算 NoSQL 关系型数据库
ecs分享
产品体验
94 0