ECS Chunk screening mechanism

Tip: select the directory on the right to quickly find the required content

Blog address: Portal


Advantages of such screening:

The entity of the whole block can be operated, which is more flexible.

In the cluster of objects, such as fish, troops, etc., the operation speed is faster.



conceptual analysis

Block and Archetype

As we can see in the first picture below, because of the same component, two entities, Entity A and Entity B, are placed in block Chuck A, while Entity C is placed in Chuck B.


Block is a lot of entities with the same components.

However, a block can contain limited entities and cannot be expanded infinitely, so as shown in the figure on the right, more identical entities form other blocks, and these blocks form the prototype.


ECS improves the efficiency of data reading through block and prototype grouping.


All the blocks under the prototype are the same size.

It is equivalent to applying for memory space in advance. No matter whether the block is full or not, it will occupy the same memory space. After a block is full, it will apply for a new empty block.


Inheriting the ForEach processing mechanism of the JobComponentSystem, only one entity can be processed. The following IJobChunk can batch process all entities in a block.

OK, the principle is over. Let's talk about how to write it.




Our Job System, red is the fixed writing method, finished writing.

using Unity.Burst;
using Unity.Collections;
using Unity.Entities;
using Unity.Jobs;
using Unity.Mathematics;
using Unity.Transforms;

public class RotationSpeedSystem_IJobChunk : JobComponentSystem
    EntityQuery m_Group;

    protected override void OnCreate ()
        //Passing the types of multiple components as parameters to filter out the entities with the specified types

m_Group = GetEntityQuery(typeof(Rotation), ComponentType.ReadOnly<RotationSpeed_IJobChunk>());

    // OnUpdate runs on the main thread.
protected override JobHandle OnUpdate(JobHandle inputDependencies)
        // Archetypechunkcomponenttype < Rotation >: component type of block (Chuck) of Rotation
        // Through the GetArchetypeChunkComponentType function, you can get the component type of a prototype's block.

ArchetypeChunkComponentType<Rotation> rotationType = GetArchetypeChunkComponentType<Rotation>();
        var rotationSpeedType = GetArchetypeChunkComponentType<RotationSpeed_IJobChunk>(true);

        var job = new RotationSpeedJob()
            RotationType = rotationType,
            RotationSpeedType = rotationSpeedType,
            DeltaTime = Time.DeltaTime

        // Execute in RotationSpeedJob is executed / paralleled here, and data is returned
return job.Schedule(m_Group, inputDependencies);

    // Our logic in ijob chunk
    // Use the [BurstCompile] attribute to compile a job with Burst. You may see significant speed ups, so try it!

RotationSpeedJob : IJobChunk
        public float DeltaTime;

public ArchetypeChunkComponentType<Rotation> RotationType;
        [ReadOnly] public ArchetypeChunkComponentType<RotationSpeed_IJobChunk> RotationSpeedType;

        // chunk is the block filtered by EntityQuery
        // The entities we filter out may be stored in different blocks, and the Execute function can only get data in one block at a time.
        // Many rotationspeedjobs may be executed (in parallel) at the same time, greatly improving performance

public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
            // GetNativeArray function, you can get a certain type of component of all entities in this block

var chunkRotations = chunk.GetNativeArray(RotationType);
            var chunkRotationSpeeds = chunk.GetNativeArray(RotationSpeedType);

            for (var i = 0; i < chunk.Count; i++)
                var rotation = chunkRotations[i];
                var rotationSpeed = chunkRotationSpeeds[i];

                chunkRotations[i] = new Rotation
                    Value = math.mul(math.normalize(rotation.Value),
                        quaternion.AxisAngle(math.up(), rotationSpeed.RadiansPerSecond * DeltaTime))




Record data. You don't have to attach it to an object, just place it on Assets.

As you can see, the features in the components below are not the [GenerateAuthoringComponent] of the previous blog. Now the script cannot be added to the object. This script also has no function of converting objects into entities. Another script on the entity below implements the conversion function.

This component is added to the entity through the method on the entity below.

using System;
using Unity.Entities;

public struct RotationSpeed_IJobChunk : IComponentData
    public float RadiansPerSecond;




For the object to be operated in the scene, add ConvertToEntity.

Also mount the following script.

  • The script inherits IConvertGameObjectToEntity and implements Convert, which is to Convert the object into an entity.
  • The script Convert, a very flexible new script to be added, is added to the entity through AddComponentData. And it means that you can add multiple components to the entity.

using Unity.Entities;
using Unity.Mathematics;
using UnityEngine;

public class RotationSpeedAuthoring_IJobChunk : MonoBehaviour, IConvertGameObjectToEntity
    public float DegreesPerSecond = 360.0F;

    public void Convert (Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
        var data = new RotationSpeed_IJobChunk { RadiansPerSecond = math.radians(DegreesPerSecond) };
        dstManager.AddComponentData(entity, data);



OK, now you can run it to see if the box is turning.

This is the end of this section. The next section describes how to create a solid from a prefab,


334 original articles published· Zan Zan 88. 190 thousand visits+
Private letter follow

Tags: Unity Attribute

Posted on Wed, 15 Apr 2020 00:18:56 -0700 by evolve4