以下文档均来源于ECS官网:
https://docs.unity3d.com/Packages/com.unity.entities@0.0/manual/ecs_entities.html
手动遍历
你也可以在一个NativeArray中直接请求所有的块,并使用诸如IJobParallelFor
之类的Job处理它们。 如果您需要以某种方式管理块,简单地遍历EntityQuery中的所有块这种简单模式已经不够适用,那么建议使用此方法。 如:
public class RotationSpeedSystem : JobComponentSystem
{
[BurstCompile]
struct RotationSpeedJob : IJobParallelFor
{
[DeallocateOnJobCompletion] public NativeArray<ArchetypeChunk> Chunks;
public ArchetypeChunkComponentType<RotationQuaternion> RotationType;
[ReadOnly] public ArchetypeChunkComponentType<RotationSpeed> RotationSpeedType;
public float DeltaTime;
public void Execute(int chunkIndex)
{
var chunk = Chunks[chunkIndex];
var chunkRotation = chunk.GetNativeArray(RotationType);
var chunkSpeed = chunk.GetNativeArray(RotationSpeedType);
var __instanceCount __= chunk.Count;
for (int i = 0; i < instanceCount; i++)
{
var rotation = chunkRotation[i];
var speed = chunkSpeed[i];
rotation.Value = math.mul(math.normalize(rotation.Value), quaternion.AxisAngle(math.up(), speed.RadiansPerSecond * DeltaTime));
chunkRotation[i] = rotation;
}
}
}
EntityQuery m_group;
protected override void OnCreate()
{
var query = new EntityQueryDesc
{
All = new ComponentType[]{ typeof(RotationQuaternion), ComponentType.ReadOnly<RotationSpeed>() }
};
m_group = GetEntityQuery(query);
}
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
var rotationType = GetArchetypeChunkComponentType<RotationQuaternion>();
var rotationSpeedType = GetArchetypeChunkComponentType<RotationSpeed>(true);
var chunks = m_group.CreateArchetypeChunkArray(Allocator.__TempJob__);
var rotationsSpeedJob = new RotationSpeedJob
{
Chunks = chunks,
RotationType = rotationType,
RotationSpeedType = rotationSpeedType,
DeltaTime = Time.deltaTime
};
return rotationsSpeedJob.Schedule(chunks.Length,32,inputDeps);
}
}
在ComponentSystem中手动遍历
虽然一般来说,这不是推荐的做法,但您还是可以使用EntityManager类手动遍历实体或块。 这些迭代方法应该只用于测试或调试代码(或者只是在进行实验时),或者在一个孤立的世界中,这个世界中有一套完全由你控制的实体。
例如,以下代码片段将会在当前Active的World中遍历所有的实体:
var entityManager = World.Active.EntityManager;
var allEntities = entityManager.GetAllEntities();
foreach (var entity in allEntities)
{
//...
}
allEntities.Dispose();
而这一段代码将会在当前Active的World中遍历所有的块:
var entityManager = World.Active.EntityManager;
var allChunks = entityManager.GetAllChunks();
foreach (var chunk in allChunks)
{
//...
}
allChunks.Dispose();