- Use burst on default systems
- Jobs like systems schedule
- World seralisation
- Custom Allocator
Create class inherited from WordInstaller
and drop it on scene
public class TestRunner : WorldInstaller
{
// if you wnat use other world config
protected override WorldConfig GetConfig() => new WorldConfig()
{
StartPoolSize = 100000, //start pool capacity
StartEntitiesAmount = 100000 //start entities capacity
};
// use Udpate for exectuing all systems
private void Update()
{
Systems.OnUpdate(Time.deltaTime, Time.time);
}
// add systems here
protected override void OnWorldCreated(ref World world)
{
Systems
.Add<MySystem1>()
.Add<MySystem2>()
.Add<MySystem3>()
.Add<MySystem4>()
...
.Add<MySystemN>()
;
}
//create entities here
protected virtual void CreateEntities(ref World world)
{
var e = world.Entity();
e.Add(new Player());
e.Add(new Input());
e.Add(new Speed{value = 4f});
e.Add(new Body2D());
e.Add(new Circle2D
{
radius = 1.3f,
layer = CollisionLayer.Player,
collideWith = CollisionLayer.Enemy | CollisionLayer.Player
});
}
//if you need to cleare some data with world
protected override void OnDestroy()
{
base.OnDestroy(); world will be disposed here
}
}
Components are just unmanaged structs with IComponent interface
public struct MySimpleComponent : IComponent
{
public int Data;
}
// if a component doesn't have any data, it will be marked as a tag and won't take up any memory,
public struct MyTagComponent : IComponent { } // it will just be used in the query for filtering.
// System.IDisposable used to clear component data to avoid leak or something like that
public struct MyDisposableComponent : IComponent, System.IDisposable
{
//unmanaged data
public float MyValue;
//unmanaged struct and etc
public NativeArray<int> MyNativeArray;
//managed classes and etc
public ObjectRef<List<int>> MyManagedList;
//unity object reference
public UnityObjectRef<Transform> MyUnityTransform;
//Dispose will be called when this component is removed from the entity or Entity.Destroy is called
public void Dispose()
{
MyNativeArray.Dispose();
MyManagedList.Dispose();
}
}
//when you need to copy some complex structure from another component. It will be executed when you call Entity.Copy()
public struct MyCopyableComponent : IComponent, ICopyable<MyCopyableComponent>
{
public NativeList<SomeData> List;
public MyCopyableComponent Copy(int to)
{
var copy = new NativeList<SomeData>(List.Length, Allocator.Persistent);
copy.CopyFrom(in List);
return new MyCopyableComponent
{
List = copy
};
}
}
[BurstCompile]
public struct MoveBulletSystem : IEntityJobSystem
{
public SystemMode Mode => SystemMode.Parallel;
public Query GetQuery(ref World world)
{
return world.Query().With<Bullet>().With<Transform>().With<Body2D>().With<Speed>().None<StaticTag>();
}
public void OnUpdate(ref Entity entity, ref State state)
{
ref var t = ref entity.Get<Transform>();
ref var b = ref entity.Get<Body2D>();
ref readonly var s = ref entity.Read<Speed>();
t.Position = math.mul(t.Rotation, math.right()) * s.value * state.Time.DeltaTime;
}
}
[BurstCompile]
public struct TestJobSystem : IJobSystem, ICreate
{
private Query _query;
public void OnCreate(ref World world)
{
_query = world.Query().None<Component1>().With<Component2>();
}
public void OnUpdate(ref State state)
{
foreach (ref var entity in _query)
{
ref var c = ref entity.Get<Component2>();
}
}
}
System for main thread. Can be struct or class
public struct ClearTransformsSystem : ISystem, IOnCreate
{
private Query _query;
public void OnCreate(ref World world)
{
query = world.Query(withDefaultNoneTypes : false) // by default Query() use some default types for excluding from filtring,
.With<DestroyEntity>() // but can this can be turned of just setting parametr to false
.With<TransformRef>();
}
public void OnUpdate(ref State state)
{
foreach (ref var entity in _query)
{
UnityEngine.Object.Destroy(entity.Get<TransformRef>().Value.Value.gameObject);
}
}
}
Also for every system can be used with some other interfaces:
ICreate
. IOnCreate(ref World world)
will be called when system are added to list of systems
IFixed
For physics or other staff with fixed tickrate. System will be called every 0.016 seconds
Just struct for accessing such things as World, Time and all dependencies chain
public struct State
{
public JobHandle Dependencies;
public World World;
public TimeData Time;
}
byte[] data = world.Serialize();
world.Deserialize(data);
TODO:
- Update README
- Unity integration without tri inspector
- Generator for generic job systems
- Add sync of to network for entity commands
- Rework allocator
- Add support of managed components