前文的SystemBase写法同样可以改为ISystem写的写法,这两段是等价的:
[BurstCompile]
partial struct TankMovementSystem : ISystem
{
public void OnCreate(ref SystemState state)
{
}
public void OnDestroy(ref SystemState state)
{
}
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
//var dt = state.World.Time.DeltaTime;
var dt = SystemAPI.Time.DeltaTime;
foreach (TransformAspect transform in SystemAPI.Query<TransformAspect>().WithAll<Tank>())
{
var pos = transform.LocalPosition;
var angle = (0.5f + noise.cnoise(pos / 10f)) * 4.0f * math.PI;
var dir = float3.zero;
math.sincos(angle, out dir.x, out dir.z);
transform.LocalPosition += dir * dt * 5.0f;
transform.LocalRotation = quaternion.RotateY(angle);
}
}
}
这里关注下 GetComponentLookup 函数,通过SystemAPI.GetComponentLookup找到当前世界的 WorldTransform 队列。同样可以通过state.GetComponentLookup获取。
[BurstCompile]
public void OnCreate(ref SystemState state)
{
// ComponentLookup structures have to be initialized once.
// The parameter specifies if the lookups will be read only or if they should allow writes.
m_WorldTransformLookup = SystemAPI.GetComponentLookup<WorldTransform>(true);
//m_WorldTransformLookup = state.GetComponentLookup<WorldTransform>(true);
}
由于OnUpdate需要每一帧都刷新所以 m_WorldTransformLookup 这个结构不能在这个函数中每一帧创建,就在OnCreate中获取一次,在OnCreate函数中使用SystemState进行计算。
// A ComponentLookup provides random access to a component (looking up an entity).
// We'll use it to extract the world space position and orientation of the spawn point (cannon nozzle).
ComponentLookup<WorldTransform> m_WorldTransformLookup;
public void OnUpdate(ref SystemState state)
{
// ComponentLookup structures have to be updated every frame.
m_WorldTransformLookup.Update(ref state);
// Creating an EntityCommandBuffer to defer the structural changes required by instantiation.
var ecbSingleton = SystemAPI.GetSingleton<BeginSimulationEntityCommandBufferSystem.Singleton>();
var ecb = ecbSingleton.CreateCommandBuffer(state.WorldUnmanaged);
// Creating an instance of the job.
// Passing it the ComponentLookup required to get the world transform of the spawn point.
// And the entity command buffer the job can write to.
var turretShootJob = new TurretShoot
{
WorldTransformLookup = m_WorldTransformLookup,
ECB = ecb
};
// Schedule execution in a single thread, and do not block main thread.
turretShootJob.Schedule();
}
对结构的增删改要放在buff内,buff又分三大Group,可以world中获取以下CommandBufferSystem(对应到不同周期),创建EntityCommandBuffer之后在其内可以对Entity进行操作。
下面是几个可以获取到的 EntityCommandBufferSystem:
BeginInitializationEntityCommandBufferSystem
EndInitializationEntityCommandBufferSystem
BeginSimulationEntityCommandBufferSystem
EndSimulationEntityCommandBufferSystem
BeginPresentationEntityCommandBufferSystem