Расширение для ecslite, которое содержит реализацию структуры quadtree, адаптированную под ECS, а так же системы для работы с ней. Не зависит от движка и каких либо сторонних библиотек, кроме ECSLite. В работе систем нет аллокаций (аллокации только на стадии кэширования)
Поддерживается установка в виде unity-модуля через git-ссылку в PackageManager или прямое редактирование Packages/manifest.json
:
"com.nenuacho.ecslite.quadtree-systems": "https://github.com/nenuacho/ecslite-quadtree.git",
Для работы систем необходимо создать сервис QuadTreeService с подходящими параметрами
var quadSvc = new QuadTreeService(new QuadBounds(Vector2.Zero, new Vector2(1000, 1000)));
Для этого сервиса корень quadtree будет расположен в нулевой координате и иметь ширину и высоту 1000. Так же в него можно передать максимальное кол-во сущностей на квадрат, после которого произойдет разделение (по умолчанию 3)
var quadSvc = new QuadTreeService(new QuadBounds(Vector2.Zero, new Vector2(1000, 1000)), 2);
На данный момент реализованны 2 системы:
- QuadTreeBuildSystem - система построения дерева
- QuadTreeFindNearestSystem - система поиска ближайшей сущности
Система построения дерева должна отрабатывать до системы поиска
_systems
.Add(new QuadTreeBuildSystem(quadSvc))
.Add(new QuadTreeFindNearestSystem(quadSvc))
.Init();
Эти системы будут обрабатывать все сущности с компонентом PositionWithNearestEntityComponent.
Поскольку система QuadTreeFindNearestSystem является многопоточной, в неё можно передать размер чанка, это будет число сущностей на поток (по умолчанию 300)
_systems
.Add(new QuadTreeBuildSystem(quadSvc))
.Add(new QuadTreeFindNearestSystem(quadSvc, 200))
.Init();
Если нужен кастомный фильтр, его так же можно передать в контрукторе систем
_systems
.Add(new QuadTreeBuildSystem(quadSvc, myFilter))
.Add(new QuadTreeFindNearestSystem(quadSvc, 200, myFilter))
.Init();
при этом PositionWithNearestEntityComponent является обязательным компонентом в фильтре
- Создать сущности с компонентом
public struct PositionWithNearestEntityComponent
{
public Vector2 Position;
public (Vector2 Position, int Entity) NearestEntity;
}
-
До работы систем из этого расширения актуализировать Position этих компонентов
-
После работы QuadTreeFindNearestSystem, можно использовать найденные данные для дальнейших задач, например:
public class DrawSystem : IEcsRunSystem
{
private EcsFilterInject<Inc<PositionWithNearestEntityComponent>> _filter;
public void Run(IEcsSystems systems)
{
foreach (var e in _filter.Value)
{
ref var quadNearest = ref _filter.Pools.Inc1.Get(e);
Debug.DrawLine(quadNearest.Position.ToUnityVec(), quadNearest.NearestEntity.Position.ToUnityVec(), Color.red);
}
}
...
Поскольку операция поиска ближайших сущностей может быть ресурсоемкой, не следует производить поиск каждый кадр, лучше подобрать более длительный интервал. А с интервалами поможет Interval Systems