DOTS 混合组件

序幕

请注意,混合组件与Project Tiny不兼容

目的

Unity 的许多现有功能还没有 DOTS 等价物(目前)。因此,在许多情况下,DOTS 项目将是混合的:经典游戏对象和 ECS 的混合。

混合组件提供了一种从 ECS 代码方便地访问 UnityEngine 组件的方法。它们最初旨在处理渲染组件,如灯光、反射探针、后期处理体积等。

与混合组件相关的主要限制包括:

  • 仅对于类似数据的组件,不会调用大多数事件函数
  • 与 GameObjects 相比没有性能优势,包括没有作业、没有 Burst、没有改进内存使用。
  • 不是通用功能,混合组件的使用是明确的(选择加入)。
  • 从实体 0.16 开始,LiveLink 不完全支持混合组件。
  • 混合组件只能在转换时创建。

组件对象

混合组件是在Component对象之上实现的,所以让我们先讨论一下什么是 Component 对象。组件对象是使用AddComponentObject添加到实体并通过GetComponentObject访问的常规 UnityEngine 组件,允许在查询和其他一些地方使用这些类型的组件。

在内部,对此类组件的引用不是存储在块中,而是存储在托管数组中。块只包含这些数组的索引,而不是存储组件本身。

这意味着对 Component 对象的每次访问都需要额外的间接访问,并且实体不“拥有”这些组件。在处理 Component 对象时必须小心谨慎,因为由于缺乏明确定义的所有权,可能会出现许多有问题的情况。例如,可以在多个实体之间共享相同的组件或销毁组件而不删除它们。

与GameObject协作 Companion GameObjects

混合组件旨在解决组件对象的所有权问题

由于常规 UnityEngine 组件不能单独存在,因此混合组件使用隐藏的游戏对象(通过HideFlags),在此上下文中我们将其称为“Companion GameObjects”。

ECS 以一种您的代码永远不必担心它们的方式使这些Companion GameObjects的管理变得透明。

笔记

该设计基于实体负责Companion GameObjects的约束。GameObject 不应修改实体或其其他组件。

转换

转换系统可以使用AddHybridComponent将一些来自创作游戏对象的 UnityEngine 组件实例声明为混合组件

[ConverterVersion("unity", 1)]
public class DoohickeyConversionSystem : GameObjectConversionSystem
{
    protected override void OnUpdate()
    {
        Entities.ForEach((Doohickey doohickey) =>
        {
            AddHybridComponent(doohickey);
        });
    }
}

在转换结束时,每个至少具有一个混合组件的创作游戏对象将被克隆,所有其他组件将从克隆中删除,并且该克隆将与实体一起存储并成为其伴侣游戏对象。

实体与其同伴 GameObject 之间的链接被恰当地命名为CompanionLinkACompanionLink是一个托管组件(IComponentData类),它也实现了IDisposableICloneable该组件管理伴随游戏对象的生命周期并包含对游戏对象的引用。

这允许实体预制实例化和实体销毁透明地工作。

笔记

这是从实体到同伴游戏对象的单向链接。没有从伴随游戏对象返回到实体的链接。

复制到 GameObject.Transform

如果存在,LocalToWorld实体组件中的变换矩阵将被复制到其同伴 GameObject 的Transform那些游戏对象总是在世界空间中,变换层次只存在于 ECS 端。

笔记

这个副本只发生在一个方向。直接修改同伴的变换是错误的,它最终会被同步系统覆盖。由于此同步系统是被动的,因此无法保证何时会发生这种情况。只有LocalToWorld在实体组件被修改时才能保证发生

posted @ 2021-09-24 00:13  alps_01  阅读(157)  评论(0编辑  收藏  举报