В ME.BECS можно очень легко и без гемора работать с данными многопоточно.
Давайте разберем как это выглядит на примере простой системы:
- У нас есть сущности с компонентом:
struct ReloadableComponent {
public float reloadTimer; // время текущей перезарядки
public float reloadTime; // сколько идет перезарядка
}- Нам нужно выбрать все сущности, на которых нет ReloadedComponent
- Для каждой сущности нужно покрутить таймер перезарядки
- Если перезарядка завершена - добавить компонент ReloadedComponent
Итак, приступим.
Сначала создадим систему:
struct ReloadSystem : IUpdate {
public void OnUpdate(ref SystemContext context) {
}
}Теперь в метод OnUpdate добавим фильтр по нашему компоненту и каркас для джобы:
struct ReloadSystem : IUpdate {
[BurstCompile]
public struct Job : IJobParallelForComponents<ReloadableComponent> {
public float dt;
public void Execute(in Ent ent, ref ReloadedComponent component) {
// тут напишем саму джобу
}
}
public void OnUpdate(ref SystemContext context) {
var dependsOn = API.Query(in context)
.Without<ReloadedComponent>()
.With<ReloadableComponent>()
.ScheduleParallelFor<Job, ReloadableComponent>(new Job() {
dt = context.deltaTime,
});
context.SetDependency(dependsOn);
}
}А теперь добавим саму логику джобы:
public struct Job : IJobParallelForComponents<ReloadableComponent> {
public float dt;
public void Execute(in Ent ent, ref ReloadedComponent component) {
component.reloadTimer += this.dt;
if (component.reloadTimer >= component.reloadTime) {
ent.Set(new ReloadedComponent());
}
}
} Ну собственно и все :)
Теперь это работает многопоточно, под берстом и может быть использовано в общем графе систем.