Planetarium Engineering Snack

How to Use Unity DOTS DynamicBuffer

(English한국어)

Hello, I’m Hyun Seungmin, Nine Chronicles developer at Planetarium. Our project is not yet using Unity DOTS but we are working hard to apply it to our next project. So from now on, I will be sharing what I’ve learned in my studies.

This time, let’s have a look at DynamicBuffer<T>. We’re going to talk about setting up a dynamic buffer on an entity and using it. Although we’re starting a few steps ahead for our very first DOTS article, I think you can catch on right away by following this piece because the skipped portion isn’t that substantial.

This article refers to the Unity Official Docs and the tutorial video.

Dev Environment

Unity
2019.3.12f1
com.unity.entities
0.10.0-preview.6

IBufferElementData Implementation

Just as components that are added to an entity must implement the IComponentData Interface, DynamicBuffer<T> must also implement the IBufferElementData Interface.

Using EntityManager.AddBuffer<T>()

Just like adding a component to an entity, we need to use EntityManager when adding buffers. Below, I’ve written a component called PlayModeTest that will be added to game objects and with that, let’s check the Entity Debugger in play mode.

Using DynamicBuffer<T>.Reinterpret<U>()

Now let’s find out how to modify the values contained in the structure of the buffer.

Using EntityManager.GetBuffer<T>()

We also need a way to access the buffer on the entity.

Authoring

GenerateAuthoringComponentAttribute allows you to add Authoring Component to a game object to make an entity. IBufferElementData can use the same method.

Using the DynamicBuffer in ComponentSystem

Now, let’s access the entity’s IntBufferElement DynamicBuffer that includes the UnitTag component by creating a system that inherits ComponentSystem.

Using the DynamicBuffer in JobComponentSystem

Let’s create a system that inherits JobComponentSystem and try to access IntBufferElement DynamicBuffer of an entity that includes the PlayerTag component.

Additional Tips

InternalBufferCapacityAttribute

Since entities are generally included in chunks, applying InternalBufferCapacityAttribute to a structure that implements IBufferElementData can specify the maximum number of elements that can exist in chunks. When the elements go over the specified limit, the buffer movers over to the heap memory. Of course, you can access the buffer through DynamicBuffer API as well.

implicit Operator

We can also write our code this way for convenience.

using Unity.Entities;

namespace DOTS_DynamicBuffer
{
  // InternalBufferCapacity specifies how many elements a buffer can have before
  // the buffer storage is moved outside the chunk.
  [InternalBufferCapacity(2)]
  [GenerateAuthoringComponent]
  public struct IntBufferElement : IBufferElementData
  {
    public int Value;

    // The following implicit conversions are optional, but can be convenient.
    public static implicit operator int(IntBufferElement e)

    {
      return e.Value;
    }

    public static implicit operator IntBufferElement(int e)

    {
      return new IntBufferElement { Value = e };
    }
  }
}

Closing

Today, we took a quick look at IBufferElementData and DynamicBuffer<T>.

You’ve probably heard a lot about object pooling when you’re making games. Since creating single-use objects is basically the same as creating garbage, pooling and reusing them can reduce frequent garbage collection and manage instance creation timing, which ultimately creates a smoother game.

Next time, let’s find out how to apply this feature and compare the before and after to see how much improvement you can get.