k.ECS

thumb
Identkfe.kecs
Typelibrary
Created
Updated
Latest Version 96481 2 KB +1 ~2
Tags architecture ecs pattern
Links s&box
SummarySimple Entity Component System framework
Description
Hybrid ECS solution for S&box [Link preview] Additional documentation available inside of the library Glossary Entity - int value, only exists if there is components associated with it Component - struct, contains data that we operate with Systems - systems allow us to change iterate over entities, changing data in their components, stonks World - container that stores entities and components Filter - filters entities based on component presence or absence Feature - list of systems Basic example var world = World.Default; var filter = new EntityFilter( world ); filter.With<Position>().With<Input>().Without<Dead>; foreach(int entity in filter){ var input = world.GetComponent<Input>( entity ); ref var position = ref world.GetComponent<Position>( entity ); if ( input.X != 0 && input.Y != 0) continue; position.X += input.X; position.Y += input.Y; } Advanced example First, we will create initializer. That's where all our game features will be initialized and updated. public class MySwordGameInitializer : InitializerBase { protected override void OnAwake() { AddFeature( new CombatFeature() ); base.OnAwake(); // must be called after we add all the features } } Second, we will create feature. It will contain all relevant systems and update them one by one. public class CombatFeature : FeatureBase { public CombatFeature() { Add( new AttackSystem() ); Add( new DefenseSystem() ); } } Third, we will create our systems. public class AttackSystem : SystemBase { private EntityFilter _filter = new EntityFilter( World.Default ).With<AttackComponent>(); public override void Update( float deltaTime ) { foreach ( var entity in _filter ) { ref var attackComponent = ref entity.Get<AttackComponent>(); // Perform attack logic here } } } Adding components We can add a component. This approach is suitable for adding tags - components without any data inside of them. // use world world.AddComponent<Input>(); // use extension to add component for entity in Default world entity.AddComponent<Input>(); Setting componetns If we want to set component with data AND/OR change existing component, we must use SetComponent instead. // use world world.SetComponent( new Input { Value = InputExample } ); // use extension to set component for entity in Default world entity.SetComponent( new Input { Value = InputExample } ); Changing component values Since we use struct for components, it is important to remember how value types differ from reference types. When you retrieve a component from an entity, you're working with a copy - not a reference to the original. This means that modifying the struct directly won't affect the component stored in the ECS unless you explicitly use ref. To safely and correctly modify component data, always use ref access when reading or updating components within systems. // ✅ Will change the position ref var position = ref entity.GetComponent<Position>(); position.Value = Vector3.Zero; // ❌ WONT change the position var position = entity.GetComponent<Position>(); position.Value = Vector3.Zero; Removing components // use world world.RemoveComponent<Input>(); // use extension to remove component for entity in Default world entity.RemoveComponent<Input>(); Linking GameObjects with ECS world 1. Create your component -> struct MyComponent 2. Create your provider -> class MyComponentProvider : EntityProvider<MyComponent> 3. Add provider to the target GameObject 4. Now you will be able to filter this GO -> Filter.With<MyComponent> !) Important: modifying component in the inspector will not work in Play mode. Currently, there is no link between instantiated component and displayed one in the inspector. [Image] Generally I'd prefer to use Morpeh, but it has issues with whitelisting, so ok then gonna make my own ecs
Hybrid ECS solution for S&box [Link preview] Additional documentation available inside of the library Glossary Entity - int value, only exists if there is components associated with it Component - struct, contains data that we operate with Systems - systems allow us to change iterate over entities, changing data in their components, stonks World - container that stores entities and components Filter - filters entities based on component presence or absence Feature - list of systems Basic example var world = World.Default; var filter = new EntityFilter( world ); filter.With<Position>().With<Input>().Without<Dead>; foreach(int entity in filter){ var input = world.GetComponent<Input>( entity ); ref var position = ref world.GetComponent<Position>( entity ); if ( input.X != 0 && input.Y != 0) continue; position.X += input.X; position.Y += input.Y; } Advanced example First, we will create initializer. That's where all our game features will be initialized and updated. public class MySwordGameInitializer : InitializerBase { protected override void OnAwake() { AddFeature( new CombatFeature() ); base.OnAwake(); // must be called after we add all the features } } Second, we will create feature. It will contain all relevant systems and update them one by one. public class CombatFeature : FeatureBase { public CombatFeature() { Add( new AttackSystem() ); Add( new DefenseSystem() ); } } Third, we will create our systems. public class AttackSystem : SystemBase { private EntityFilter _filter = new EntityFilter( World.Default ).With<AttackComponent>(); public override void Update( float deltaTime ) { foreach ( var entity in _filter ) { ref var attackComponent = ref entity.Get<AttackComponent>(); // Perform attack logic here } } } Adding components We can add a component. This approach is suitable for adding tags - components without any data inside of them. // use world world.AddComponent<Input>(); // use extension to add component for entity in Default world entity.AddComponent<Input>(); Setting componetns If we want to set component with data AND/OR change existing component, we must use SetComponent instead. // use world world.SetComponent( new Input { Value = InputExample } ); // use extension to set component for entity in Default world entity.SetComponent( new Input { Value = InputExample } ); Changing component values Since we use struct for components, it is important to remember how value types differ from reference types. When you retrieve a component from an entity, you're working with a copy - not a reference to the original. This means that modifying the struct directly won't affect the component stored in the ECS unless you explicitly use ref. To safely and correctly modify component data, always use ref access when reading or updating components within systems. // ✅ Will change the position ref var position = ref entity.GetComponent<Position>(); position.Value = Vector3.Zero; // ❌ WONT change the position var position = entity.GetComponent<Position>(); position.Value = Vector3.Zero; Removing components // use world world.RemoveComponent<Input>(); // use extension to remove component for entity in Default world entity.RemoveComponent<Input>(); Linking GameObjects with ECS world 1. Create your component -> struct MyComponent 2. Create your provider -> class MyComponentProvider : EntityProvider<MyComponent> 3. Add provider to the target GameObject 4. Now you will be able to filter this GO -> Filter.With<MyComponent> !) Important: modifying component in the inspector will not work in Play mode. Currently, there is no link between instantiated component and displayed one in the inspector. [Image] Generally I'd prefer to use Morpeh, but it has issues with whitelisting, so ok then gonna make my own ecs
Votes 3 0 2
Error Rate0%
Data
{}