Skip to content

Commit

Permalink
added config, updated transform component, samples
Browse files Browse the repository at this point in the history
  • Loading branch information
KOTlK committed Jun 8, 2023
1 parent e8dcd0c commit 6b40910
Show file tree
Hide file tree
Showing 25 changed files with 308 additions and 177 deletions.
2 changes: 1 addition & 1 deletion Package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "com.kotlk.celllistsecs",
"version": "0.1.3",
"version": "0.2.0",
"displayName": "Cell Lists",
"description": "Simple cell lists implementation for dividing game world into pieces",
"unity": "2021.3",
Expand Down
37 changes: 28 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,41 @@ Make sure you have standalone git installed.

# Usage

Simple example of usage with scene can be found inside `Samples~` folder
Simple example of usage can be found inside `Samples~` folder

- Add `CellListsInitSystem` into your systems
- Add `InsertTransformSystem` into your systems
- Add `RemoveFromCellListsSystem` into your systems
- Add `CellListsRebuildSystem` into your systems
- Create entity with `CreateCellLists` component attached to it
- Fill component values
- Create `CellListsConfig` and inject it in your systems

``` C#
var world = new EcsWorld();
var systems = new EcsSystems(world);
var config = new CellListsConfig()
{
Center = Vector2.zero,
Size = new Vector2(100, 100),
Height = 10,
Width = 10
};

systems
.Add(new CellListsInitSystem())
.Add(new InsertTransformSystem())
.Add(new RemoveFromCellListsSystem())
.Add(new CellListsRebuildSystem())
.Inject(config)
.Init();
```

Sequence above will create cells in the next `CellListsInitSystem.Execute` call.

To insert `Transform` into cells simply add component `InsertInCellLists` to transform.
To insert `Transform` into cells add component `InsertInCellLists` to transform.

To get cells, filter components with `Cell, CellNeighbours` components.
To remove `Transform` component from cell, create new entity with `RemoveFromCellLists` component on it and fill field `TransformEntity`

`Cell` is a cell. `CellNeighbours` contains indexes of `Cell`s, closest to the cell, and indexes of `Transform` components, that belongs to the cell
To get cells, filter components with `Cell, CellNeighbours` components.

`CellListsRebuildSystem` can be called with some interval via [Interval Systems](https://github.com/nenuacho/ecslite-interval-systems) extension.
`Cell` is a cell. `CellNeighbours` contains indexes of `Cell`s, closest to the cell, and indexes of `Transform` components, that belongs to the cell. Transform components contains its position and cell, it belongs to.

You can Replace `Transform` component with any component, that have `public UnityEngine.Vector2 Position` field in it by cloning repository and deleting my transform from `Components` folder or by downloading unity package and doing the same.
`CellListsRebuildSystem` can be called with some interval via [Interval Systems](https://github.com/nenuacho/ecslite-interval-systems) extension.
9 changes: 9 additions & 0 deletions Runtime/Components/Cell.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,14 @@ public struct Cell
{
public AABB AABB;
public Vector2 Position;

public bool ContainsPoint(Vector2 point)
{
var halfExtents = AABB.HalfExtents;
return Position.x + halfExtents.x >= point.x &&
Position.y + halfExtents.y >= point.y &&
Position.x - halfExtents.x <= point.x &&
Position.y - halfExtents.y <= point.y;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
namespace CellListsECS.Runtime.Components
{
[Serializable]
public struct CreateCellLists
public class CellListsConfig
{
public Vector2 Size;
public Vector2 Center;
Expand Down
3 changes: 3 additions & 0 deletions Runtime/Components/CellListsConfig.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions Runtime/Components/CreateCellLists.cs.meta

This file was deleted.

7 changes: 7 additions & 0 deletions Runtime/Components/RemoveFromCellLists.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace CellListsECS.Runtime.Components
{
public struct RemoveFromCellLists
{
public int TransformEntity;
}
}
3 changes: 3 additions & 0 deletions Runtime/Components/RemoveFromCellLists.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Runtime/Components/Transform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ namespace CellListsECS.Runtime.Components
public struct Transform
{
public Vector2 Position;
public int Cell;
}
}
202 changes: 98 additions & 104 deletions Runtime/Systems/CellListsInitSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,127 +6,121 @@

namespace CellListsECS.Runtime.Systems
{
public class CellListsInitSystem : IEcsRunSystem
public class CellListsInitSystem : IEcsInitSystem
{
private readonly EcsFilterInject<Inc<CreateCellLists>> _filter = default;
private readonly EcsPoolInject<CreateCellLists> _commands = default;
private readonly EcsCustomInject<CellListsConfig> _cellListsConfig = default;
private readonly EcsPoolInject<Cell> _cells = default;
private readonly EcsPoolInject<CellNeighbours> _neighbours = default;

public void Run(IEcsSystems systems)
public void Init(IEcsSystems systems)
{
foreach (var entity in _filter.Value)
var config = _cellListsConfig.Value;

var length = config.Width * config.Height;
var size = config.Size;
var width = config.Width;
var height = config.Height;
var centerPosition = config.Center;
var overall = new AABB
{
ref var command = ref _commands.Value.Get(entity);

var length = command.Width * command.Height;
var size = command.Size;
var width = command.Width;
var height = command.Height;
var centerPosition = command.Center;
var overall = new AABB
{
Size = size
};
var cellSize = new Vector2(size.x / width, size.y / height);
var cells = new(Cell, int)[length]; // cell, entity
var overallHalfExtents = overall.HalfExtents;
var startPosition = new Vector2(centerPosition.x - overallHalfExtents.x,
centerPosition.y + overallHalfExtents.y);
var currentPosition = startPosition;
var right = cellSize.x;
var down = -cellSize.y;
var currentColumn = 0;


for (var i = 0; i < length; i++)
{
var cell = new Cell()
{
AABB = new AABB()
{
Size = cellSize
},
Position = currentPosition
};
var cellEntity = systems.GetWorld().NewEntity();
cells[i] = (cell, cellEntity);
Size = size
};
var cellSize = new Vector2(size.x / width, size.y / height);
var cells = new (Cell, int)[length]; // cell, entity
var overallHalfExtents = overall.HalfExtents;
var startPosition = new Vector2(centerPosition.x - overallHalfExtents.x,
centerPosition.y + overallHalfExtents.y);
var currentPosition = startPosition;
var right = cellSize.x;
var down = -cellSize.y;
var currentColumn = 0;

currentPosition.x += right;
currentColumn++;
if (currentColumn == width)
{
currentPosition.x = startPosition.x;
currentPosition.y += down;
currentColumn = 0;
}
}

// pure madness
int[] GetClosestIndexesFor(int i)
for (var i = 0; i < length; i++)
{
var cell = new Cell()
{
var leftIndex = i - 1;
var rightIndex = i + 1;
var upIndex = i - width;
var downIndex = i + width;
var leftUpIndex = i - width - 1;
var rightUpIndex = i - (width - 1);
var rightDownIndex = i + width + 1;
var leftDownIndex = i + (width - 1);
var leftExist = i % width != 0 && leftIndex >= 0;
var rightExist = rightIndex % width != 0 && rightIndex < length;
var upExist = upIndex >= 0;
var downExist = downIndex < length;
var leftUpExist = leftUpIndex >= 0 && i % width != 0;
var rightUpExist = rightUpIndex % width != 0 && rightUpIndex >= 0;
var rightDownExist = rightDownIndex < length && rightDownIndex % width != 0;
var leftDownExist = leftDownIndex < length && i % width != 0;
var list = new List<int>();

if (rightExist)
list.Add(rightIndex);
if (leftExist)
list.Add(leftIndex);
if (upExist)
list.Add(upIndex);
if (downExist)
list.Add(downIndex);
if (leftUpExist)
list.Add(leftUpIndex);
if (rightUpExist)
list.Add(rightUpIndex);
if (rightDownExist)
list.Add(rightDownIndex);
if (leftDownExist)
list.Add(leftDownIndex);
AABB = new AABB()
{
Size = cellSize
},
Position = currentPosition
};
var cellEntity = systems.GetWorld().NewEntity();
cells[i] = (cell, cellEntity);

return list.ToArray();
}

for (var i = 0; i < length; i++)
currentPosition.x += right;
currentColumn++;
if (currentColumn == width)
{
var neighbours = GetClosestIndexesFor(i);
var list = new int[neighbours.Length];
for (var j = 0; j < neighbours.Length; j++)
{
var (_, neighbourEntity) = cells[neighbours[j]];
list[j] = neighbourEntity;
}
currentPosition.x = startPosition.x;
currentPosition.y += down;
currentColumn = 0;
}
}

// pure madness
int[] GetClosestIndexesFor(int i)
{
var leftIndex = i - 1;
var rightIndex = i + 1;
var upIndex = i - width;
var downIndex = i + width;
var leftUpIndex = i - width - 1;
var rightUpIndex = i - (width - 1);
var rightDownIndex = i + width + 1;
var leftDownIndex = i + (width - 1);
var leftExist = i % width != 0 && leftIndex >= 0;
var rightExist = rightIndex % width != 0 && rightIndex < length;
var upExist = upIndex >= 0;
var downExist = downIndex < length;
var leftUpExist = leftUpIndex >= 0 && i % width != 0;
var rightUpExist = rightUpIndex % width != 0 && rightUpIndex >= 0;
var rightDownExist = rightDownIndex < length && rightDownIndex % width != 0;
var leftDownExist = leftDownIndex < length && i % width != 0;
var list = new List<int>();

ref var neighboursComponent = ref _neighbours.Value.Add(cells[i].Item2);
if (rightExist)
list.Add(rightIndex);
if (leftExist)
list.Add(leftIndex);
if (upExist)
list.Add(upIndex);
if (downExist)
list.Add(downIndex);
if (leftUpExist)
list.Add(leftUpIndex);
if (rightUpExist)
list.Add(rightUpIndex);
if (rightDownExist)
list.Add(rightDownIndex);
if (leftDownExist)
list.Add(leftDownIndex);

neighboursComponent.NeighboursEntities = list;
}
return list.ToArray();
}

foreach (var (cell, cellEntity) in cells)
for (var i = 0; i < length; i++)
{
var neighbours = GetClosestIndexesFor(i);
var list = new int[neighbours.Length];
for (var j = 0; j < neighbours.Length; j++)
{
ref var cellComponent = ref _cells.Value.Add(cellEntity);
cellComponent = cell;
ref var neighbours = ref _neighbours.Value.Get(cellEntity);
neighbours.ContainingTransforms = new List<int>();
var (_, neighbourEntity) = cells[neighbours[j]];
list[j] = neighbourEntity;
}

systems.GetWorld().DelEntity(entity);
ref var neighboursComponent = ref _neighbours.Value.Add(cells[i].Item2);

neighboursComponent.NeighboursEntities = list;
}

foreach (var (cell, cellEntity) in cells)
{
ref var cellComponent = ref _cells.Value.Add(cellEntity);
cellComponent = cell;
ref var neighbours = ref _neighbours.Value.Get(cellEntity);
neighbours.ContainingTransforms = new List<int>();
}
}
}
Expand Down
Loading

0 comments on commit 6b40910

Please sign in to comment.