FAQ - OneYoungMean/Entitas-CSharp-OYM GitHub Wiki

跳到内容

Search or jump to…

拉请求 问题 市井 探索 @ MkVno2 登出 403 3015 590 sschmid / Entitas-CSharp# Frequently Asked Questions



Q: Latest Unity also has ECS, should i learn Unity's ECS first or Entitas?

A: Answer from #695

Entitas and Unity ECS are both implementations of Entity Component System Architecture. They share a lot of the same concepts, the implementation is different though.

As you might have seen from the YouTube videos, we introduced Entitas back in 2015 already. My advise that I can give you on what to learn first strongly depends on your goals. If you want to build and release a game this year, I recommend using Entitas. It's production ready, has been around for some years and is battle tested on multiple platforms like PC, mobile, VR, etc. There's a healthy community which can help and answer questions. There are also a bunch of helpful features that are not available in Unity ECS, like Reactive Systems and Entitas Events. We developed a lot of conventions and guidelines to solve most of the problems already, which is a huge benefit in my opinion.

Unity stresses that their ECS is not production ready, but if you want to learn ECS I think it's worth checking out. Also, if you know that your game will require heavy multithreading, Unity ECS will be a great option because of their tight integration with the C# Job System. Keep in mind that apis might change in the future and that best practises will develop over time.

@mzaks wrote a blog post about features that you find in Entitas which he misses in Unity ECS

https://medium.com/@icex33/my-wish-list-for-unity3d-ecs-1f3985bbe308


Q: How do I regenerate code when there are compile errors?

A: Entitas code generation uses reflection, so it requires a solution with no compile errors. Renaming or editing components break links in generated code and cause compile errors, preventing you from regenerating your code. So you will have to first fix any compile errors before you will be able to regenerate your code.

Component Editing Guide

You can rename component fields safely without regeneration as long as you apply rename-refactoring (i.e. you change the name in the rest of your code base at the same time).

You cannot rename components or add/delete fields in components without breaking the generated code. Here is a guide to dealing with this problem:

  1. Create a new folder and name it StreamingAssets (anything placed in this folder wont compile).
  2. Move all non-generated code into this new folder (e.g. Components, Systems, GameController, etc.).
  3. Delete the entire contents of the generated folder.
  4. Generate new code (this will create new contexts and features).
  5. Move your components back to their original location and perform refactoring.
  6. Generate code again (this will create new component files).
  7. Move the rest of your code back into your project.
  8. Fix errors in your systems if the changes you made cause any.
  9. Your done!

Alternatively, you can eliminate these steps and the issue itself entirely when refactoring by using the new Roslyn code generator available on the Asset Store.

See also: Code Generator


Q: How do I fix "Could Not Find .csproj" error message?

A: This error message means that either the project path is incorrect or the file doesn't exist.

First ensure that a project file already exist by selecting Assets>Open C# Project from the toolbar. Doing this will generate a new project file if one doesn't already exist. Then right-click on the Assets folder in the Unity project window and select Show in Explorer and ensure that the file found there that ends with .csproj matches the file name set in the Entitas project path (e.g. "Assembly-CSharp.csproj").

Q: How do I fix "Could not load file or assembly" error?

Cound not load Assembly-CSharp.dll

A: You'll receive this error when either the assembly file doesn't exist or the file path set in preferences is incorrect.

In new empty Unity projects you'll receive this error because the file has not yet been generated by Unity. To make Unity generate the file just open your C# project by going to the toolbar and selecting Assets>Open C# Project. Then verify that the path is correct by opening your Library/ScriptAssemblies/ folder located in the root of your Unity project folder and ensuring the Assemblies path in Entitas preferences matches it.

ScriptAssemblies folder

code_generator_first_setup_highlight2


Q: Should I store references to entities inside components?

A: Storing direct references to other entities is not recommended (why?). Instead make use of the PrimaryEntityIndex along with a unique entity ID generator to create an IdComponent. In your game controller you can subscribe to the OnEntityCreated event on each of your contexts to invoke your id generator and assign an IdComponent to the newly created entity. Below is an example of such a system using an integer IdComponent which takes its value from a unique integer on each entity (its creationIndex).

Components.cs

[Game, Input, Ui]  // contexts here
public class IdComponent :IComponent {
    [PrimaryEntityIndex]
    public int value;
}

ContextsIdExtensions.cs

using System;
using Entitas;

public static class ContextsIdExtensions
{
    public static void SubscribeId (this Contexts contexts)
    {
        foreach (var context in contexts.allContexts)
        {
            if (Array.FindIndex(context.contextInfo.componentTypes, v => v == typeof(IdComponent)) >= 0)
            {
                context.OnEntityCreated += AddId;
            }
        }
    }

    public static void AddId (IContext context, IEntity entity)
    {
        (entity as IIdEntity).ReplaceId(entity.creationIndex);
    }
}

To auto-assign ids on entity creation do the following

GameController.cs


public class GameController : MonoBehaviour
{
    private Systems _systems;

    void Start()
    {
        Contexts contexts = Contexts.sharedInstance;
        contexts.SubscribeId();

        // ... systems init
    }
}

Note: The IIdEntity interface will only be generated if the component has multiple contexts, such as [Game, Input, Ui] in the example. If it is only in a single context, EG [Game] it will not generate the Interface.

To find an entity using its ID, call context.GetEntityWithId(id);. If it is null the entity was not found.


Q: I created specific assemblies (xx.assembly.json) and now components aren't being generated.

A: Entitas doesn't know about your assemblies. Go to Tools>Entitas>Preferences and make sure you add your newly generated assembly files path to the assemblies field (separated by a comma)

code_generator_first_setup_highlight2


Q: How to create custom CodeGenerator?

  1. Create a class inside any subfolder of the Editor folder in Unity (Unity Manual - Special Folder Names)
  2. Add a using Entitas.CodeGeneration; statement and implement an ICodeGenerator interface
  3. Open Entitas.properties file (located at the root of the project) and add your Assembly-CSharp-Editor.dll full path to the Entitas.CodeGeneration.CodeGenerator.Plugins key. Usually this assembly is located at Library/ScriptAssemblies/Assembly-CSharp-Editor.dll. This is needed for the Code Generation system to be able to find your custom generator implementations (so it appears inside Entitas properties window)
  4. Make sure to add a folder path of other Unity dlls (Assembly-CSharp.dll and Assembly-CSharp-firstpass.dll) to the Entitas.CodeGeneration.CodeGenerator.SearchPaths key (example: Match-One - Entitas.properties)

Now the code generator will find your custom ICodeGenerator and will display in the drop down. Steps 3 and 4 can be executed once in a project's lifetime. All key-values stay the same if you continue adding new generators to the Editor scripts folder


Q: Entity gets destroyed in one system and further systems can't react to it.

One way to prevent this is creating destroy flag component. See DestroyComponent, DestroySystem


Q: Events feature does not trigger

A: Check if you did all steps for creating an event:

  1. Add [Event(false)] or [Event(true)] attribute to a component class
  2. If your component is a flag (has zero public members), in order to track both true and false states also add "removed" version of event, eg [Event(true, EventType.Removed)]
  3. Generate
  4. Add event systems to Systems per context, somewhere in the end after all modifying systems
  5. Implement event listener interface
  6. Get entity for entity event or create new entity for a context event, add listener to this entity
  7. If your listener is MonoBehaviour add it to your GameObject/prefab

After making these steps adding/replacing component should reactively trigger listeners

To Do: Make separate wiki page with event feature description


To Do

See #402 See #378

(issue links should be summarized and presented on the page) 代码 问题94 提取请求1 项目 0 Wiki Insights
常问问题 c0ffeeartc编辑了此页面 on 29 May · 40次修订 经常问的问题 最新的Unity还有ECS,我应该首先学习Unity的ECS还是Entitas? 如果出现编译错误,如何重新生成代码? 我如何修复“找不到.csproj”错误消息? 如何修复“无法加载文件或程序集”错误? 我应该存储对组件内部实体的引用吗? 我创建了特定的程序集,现在没有生成组件 如何创建自定义CodeGenerator? 实体在一个系统中被破坏,而其他系统无法对其做出反应 事件功能不会触发 问:最新的Unity还有ECS,我应该首先学习Unity的ECS还是Entitas? 答:来自#695的回答

Entitas和Unity ECS都是实体组件系统架构的实现。它们共享许多相同的概念,但实现方式不同。

正如您在YouTube视频中看到的那样,我们已经在2015年推出了Entitas。我的建议是,我可以先给你学习什么,这在很大程度上取决于你的目标。如果您想在今年构建和发布游戏,我建议您使用Entitas。它的生产准备就绪,已存在多年,并在PC,移动,VR等多种平台上进行了战斗测试。有一个健康的社区可以帮助和回答问题。Unity ECS中还提供了许多有用的功能,如Reactive Systems和Entitas Events。我们已经制定了许多公约和指南来解决大部分问题,这在我看来是一个巨大的好处。

Unity强调他们的ECS不是生产准备好的,但如果你想学习ECS,我认为值得一试。此外,如果您知道您的游戏需要大量多线程,Unity ECS将是一个很好的选择,因为它们与C#作业系统紧密集成。请记住,apis可能会在未来发生变化,并且最佳实践会随着时间的推移而发展。

@mzaks撰写了一篇博文,介绍了他在Entitas中发现的功能,他在Unity ECS中遗漏了这些功能

https://medium.com/@icex33/my-wish-list-for-unity3d-ecs-1f3985bbe308

问:如果出现编译错误,如何重新生成代码? 答:Entitas代码生成使用反射,因此它需要一个没有编译错误的解决方案。重命名或编辑组件会破坏生成的代码中的链接并导致编译错误,从而阻止您重新生成代码。因此,您必须首先修复任何编译错误,然后才能重新生成代码。

组件编辑指南 你可以安然无再生,只要你申请重命名,重命名重构分量场(即你在你的代码库的其余部分在同一时间更改名称)。

您不能在不破坏生成的代码的情况下重命名组件或添加/删除组件中的字段。以下是处理此问题的指南:

创建一个新文件夹并将其命名为StreamingAssets(放置在此文件夹中的任何内容都不会编译)。 将所有未生成的代码移动到此新文件夹中(例如,组件,系统,GameController等)。 删除生成的文件夹的全部内容。 生成新代码(这将创建新的上下文和功能)。 将组件移回原始位置并执行重构。 再次生成代码(这将创建新的组件文件)。 将其余代码移回项目中。 如果您所做的更改导致任何错误,请修复系统中的错误。 你做完了! 或者,您可以使用资源商店中提供的新Roslyn代码生成器在重构时完全消除这些步骤和问题本身。

另请参见:代码生成器

问:如何修复“找不到.csproj”错误消息? A: This error message means that either the project path is incorrect or the file doesn't exist.

First ensure that a project file already exist by selecting Assets>Open C# Project from the toolbar. Doing this will generate a new project file if one doesn't already exist. Then right-click on the Assets folder in the Unity project window and select Show in Explorer and ensure that the file found there that ends with .csproj matches the file name set in the Entitas project path (e.g. "Assembly-CSharp.csproj").

Q: How do I fix "Could not load file or assembly" error? Cound没有加载Assembly-CSharp.dll

A: You'll receive this error when either the assembly file doesn't exist or the file path set in preferences is incorrect.

在新的空Unity项目中,您将收到此错误,因为Unity尚未生成该文件。要使Unity生成文件,只需打开C#项目,方法是转到工具栏并选择Assets> Open C#Project。然后验证路径是否正确打开您的Library/ScriptAssemblies/位于您的统一项目文件夹的根文件夹,并确保大会在Entitas喜好路径进行匹配。

ScriptAssemblies文件夹

code_generator_first_setup_highlight2

问:我应该在组件内存储对实体的引用吗? 答:不推荐存储直接引用其他实体(为什么?)。而是使用PrimaryEntityIndex以及唯一的实体ID生成器来创建IdComponent。在您的游戏控制器中,您可以OnEntityCreated在每个上下文中订阅事件以调用您的id生成器并将IdComponent分配给新创建的实体。下面是使用整数IdComponent的这种系统的示例,该整数IdComponent从每个实体(其creationIndex)上的唯一整数获取其值。

Components.cs

[ Game,Input,Ui ] // contexts here public class IdComponent:IComponent { [ PrimaryEntityIndex ] public int value ; } ContextsIdExtensions.cs

使用 系统 ; 使用 Entitas ;

公共 静态 类 ContextsIdExtensions { public static void SubscribeId(this Contexts contexts) { 的foreach(VAR 上下文 中 的上下文。allContexts) { 如果(阵列。FindIndex(上下文。contextInfo。componentTypes,v => v == typeof运算(IdComponent))> = 0) { 背景。OnEntityCreated + = AddId ; } } }

public  static  void  AddId(IContext  context,IEntity  entity)
{
    (实体 为 IIdEntity)。ReplaceId(实体。creationIndex);
}

} 要在实体创建时自动分配ID,请执行以下操作

GameController.cs

公共 类 GameController:MonoBehaviour { 私人 系统 _ 系统 ;

void  Start()
{
    上下文 上下文 =  上下文。sharedInstance ;
    背景。SubscribeId();

    // ...系统初始化
}

} 注意:仅当组件具有多个上下文时才会生成IIdEntity接口,例如[Game, Input, Ui]在示例中。如果它仅在单个上下文中,[Game]则它不会生成接口。

要使用其ID查找实体,请致电context.GetEntityWithId(id);。如果为null,则找不到实体。

问:我创建了特定的程序集(xx.assembly.json),现在没有生成组件。 答:Entitas不了解您的程序集。转到工具> Entitas>首选项,并确保将新生成的程序集文件路径添加到程序集字段(以逗号分隔)

code_generator_first_setup_highlight2

问:如何创建自定义CodeGenerator? Editor在Unity 中的文件夹的任何子文件夹内创建一个类(Unity手册 - 特殊文件夹名称) Add a using Entitas.CodeGeneration; statement and implement an ICodeGenerator interface Open Entitas.properties file (located at the root of the project) and add your Assembly-CSharp-Editor.dll full path to the Entitas.CodeGeneration.CodeGenerator.Plugins key. Usually this assembly is located at Library/ScriptAssemblies/Assembly-CSharp-Editor.dll. This is needed for the Code Generation system to be able to find your custom generator implementations (so it appears inside Entitas properties window) Make sure to add a folder path of other Unity dlls (Assembly-CSharp.dll and Assembly-CSharp-firstpass.dll) to the Entitas.CodeGeneration.CodeGenerator.SearchPaths key (example: Match-One - Entitas.properties) Now the code generator will find your custom ICodeGenerator and will display in the drop down. Steps 3 and 4 can be executed once in a project's lifetime. All key-values stay the same if you continue adding new generators to the Editor scripts folder

Q: Entity gets destroyed in one system and further systems can't react to it. One way to prevent this is creating destroy flag component. See DestroyComponent, DestroySystem

Q: Events feature does not trigger A: Check if you did all steps for creating an event:

Add [Event(false)] or [Event(true)] attribute to a component class If your component is a flag (has zero public members), in order to track both true and false states also add "removed" version of event, eg [Event(true, EventType.Removed)] Generate Add event systems to Systems per context, somewhere in the end after all modifying systems Implement event listener interface Get entity for entity event or create new entity for a context event, add listener to this entity If your listener is MonoBehaviour add it to your GameObject/prefab 在完成这些步骤之后,添加/替换组件应该反应性地触发侦听器

待办事项:使用事件功能描述创建单独的Wiki页面

去做 见#402 见#378

(问题链接应汇总并显示在页面上)

指南: 简介 - 安装 - 升级 - 常见问题 - 食谱 - 贡献

需要帮忙? 提出问题或创建问题。

通过https://gitter.im/sschmid/Entitas-CSharp加入聊天 Twitter跟我来 Twitter跟我来 建立状态 最新发布的

第27页 主要 家 介绍 橱窗 安装 教程 例子 常问问题 菜谱 脚本API 扩展 路线图 手册 基础 系统 属性 代码生成器 其他 Wiki需要帮助 在本地克隆此Wiki

https://github.com/sschmid/Entitas-CSharp.wiki.git ©2018 GitHub,Inc。 条款 隐私 安全 状态 救命 联系GitHub 价钱 API 训练 博客 关于 按h打开包含更多详细信息的悬浮卡。