Unity ECS 02 Component的一般用法

原文:https://docs.unity3d.com/Packages/[email protected]/manual/component_data.html

组件的一般用法

Unity中的ComponentData(也就是ECS中通常所说的组件(Component))是只包含了某个实体(Entity)中的一部分数据(而非行为)的结构。 ComponentData不应包含方法,除了一些工具性的用来访问数据的方法。 您应该在系统(System)中实现所有游戏逻辑和行为。 就面向对象的Unity系统而言,这有点类似于Component类,但是只包含变量。
Unity ECS API提供了一个名为IComponentData的接口,您可以在代码中实现该接口来声明这是一个组件类型。

IComponentData

传统的Unity组件(继承MonoBehaviour的类)是面向对象的类,其中包含某个具体行为的数据和方法。 IComponentData是纯ECS样式的组件,这意味着它没有定义任何行为,仅定义了数据。 您应该将IComponentData实现为struct而不是类,这意味着默认情况下,它是通过值而不是通过引用复制的。 通常,您需要使用以下模式来修改数据:

var transform = group.transform[index]; // Read

transform.heading = playerInput.move; // Modify
transform.position += deltaTime * playerInput.move * settings.playerMoveSpeed;

group.transform[index] = transform; // Write

IComponentData结构不得包含对托管对象的引用。 这是因为ComponentData驻留在简单的非垃圾收集的跟踪块内存中,这具有许多性能优势。

托管的 IComponentData

使用托管的IComponentData(也就是说使用类而不是结构声明的IComponentData)有助于将现有代码以零碎的方式移植到ECS上,与不适合ISharedComponentData的托管数据进行互操作,或为数据布局提供原型。(嗯,完全没看懂)
这些组件的使用方式与值类型IComponentData相同。 但是,ECS在内部以完全不同(且较慢)的方式处理它们。 如果不需要托管组件支持,请在应用程序的 Player Settings(Edit > Project Settings > Player > Scripting Define Symbols)中定义UNITY_DISABLE_MANAGED_COMPONENTS。
由于托管IComponentData是托管类型,因此与值类型IComponentData相比,它具有以下性能缺点:

  • 不能与Burst编译器一起使用
  • 不能在作业结构中使用
  • 它不能使用块内存
  • 需要垃圾收集

您应该尝试限制托管组件的数量,并尽可能多地使用blittable类型。
托管的IComponentData必须实现IEquatable接口并重写Object.GetHashCode()。此外,为了序列化,托管组件必须是默认可构造的(大概就是说,具有无参数的构造函数?)。
必须在主线程上设置组件的值。为此,使用EntityManager或EntityCommandBuffer。因为组件是引用类型,所以您可以更改组件的值,而不需要在块与块之间移动实体,这与ISharedComponentData不同。这不会创建一个同步点。(依然没看懂)
但是,尽管托管组件在逻辑上与值类型组件分开存储,但它们仍然会影响实体的EntityArchetype定义。 这样,向实体添加新的托管组件仍会导致ECS创建新的原型(如果尚不存在匹配的原型),并将实体移至新的Chunk。

你可能感兴趣的:(Unity3D,ECS)