Расширение для 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