All Projects → actionk → ECSEntityBuilder

actionk / ECSEntityBuilder

Licence: MIT, Unknown licenses found Licenses found MIT LICENSE Unknown LICENSE.meta
Unity ECS Entity Builder/Wrapper

Programming Languages

C#
18002 projects

Projects that are alternatives of or similar to ECSEntityBuilder

HexMapMadeInUnity2019ECS
Auto Create Map System Made with Unity 2019 ECS
Stars: ✭ 54 (+38.46%)
Mutual labels:  ecs, entities, dots
Unitymmo
an unity mmo demo, base on ecs(game play), xlua(ui)
Stars: ✭ 780 (+1900%)
Mutual labels:  ecs, entities
UnityDOTS-Thesis
Bachelor's degree thesis on Unity DOTS architecture
Stars: ✭ 14 (-64.1%)
Mutual labels:  ecs, dots
Uecs
Ubpa Entity-Component-System (U ECS) in Unity3D-style
Stars: ✭ 174 (+346.15%)
Mutual labels:  ecs, entities
SpaceWar-ECS
A space war game made with ECS and JobSystem in Unity.
Stars: ✭ 26 (-33.33%)
Mutual labels:  ecs, dots
VertexAnimation
Vertex animation baking tool, shaders and animation system for Unity DOTS/ECS.
Stars: ✭ 132 (+238.46%)
Mutual labels:  ecs, dots
LockstepECS
Fast Lockstep ECS Framework
Stars: ✭ 177 (+353.85%)
Mutual labels:  ecs, dots
ECSCombat
A space battle simulation, based around Unity ECS framework
Stars: ✭ 81 (+107.69%)
Mutual labels:  ecs, dots
Deb Dots
Debian GNU/Linux dot files.
Stars: ✭ 49 (+25.64%)
Mutual labels:  dots
Game-Tricks
Game Tricks !!!
Stars: ✭ 91 (+133.33%)
Mutual labels:  dots
flhooks
React like Hooks implementation for Flutter.
Stars: ✭ 38 (-2.56%)
Mutual labels:  builder
designable
🧩 Make everything designable 🧩
Stars: ✭ 2,156 (+5428.21%)
Mutual labels:  builder
Scripts-Sploits
A number of scripts POC's and problems solved as pentests move along.
Stars: ✭ 37 (-5.13%)
Mutual labels:  builder
pnzr
pnzr is docker deploy tool for ecs.
Stars: ✭ 31 (-20.51%)
Mutual labels:  ecs
Discord-AIO
Discord AIO (All In One) - discord stealer/token grabber builder with token checks, webhook spammer, obfuscation, encryption, crypto miner, RAT and a lot of extra features.
Stars: ✭ 105 (+169.23%)
Mutual labels:  builder
ocibuilder
A tool to build OCI compliant images
Stars: ✭ 63 (+61.54%)
Mutual labels:  builder
terraform-aws-ecs-cluster
Creates an ECS cluster backed by an Auto Scaling Group
Stars: ✭ 57 (+46.15%)
Mutual labels:  ecs
grapesjs-plugin-forms
Set of form components and blocks for the GrapesJS editor
Stars: ✭ 39 (+0%)
Mutual labels:  builder
ECS-CommunityEdition
ECS Community Edition "Free & Frictionless"
Stars: ✭ 125 (+220.51%)
Mutual labels:  ecs
patterns
Good practices to create code in Java, open to other languages. ⚡
Stars: ✭ 14 (-64.1%)
Mutual labels:  builder

Unity ECS EntityBuilder

This project is a wrapper around Unity ECS entities that allows one to simplify the process of creating / modifying entities.

Install

You can either just put the files into Assets/Plugins/ECSEntityBuilder or use it as a submodule:

git submodule add https://github.com/actionk/UnityECSEntityBuilder.git Assets/Plugins/ECSEntityBuilder

Usage

EntityWrapper

Wrapping an existing entity

Entity Wrapper allows you to wrap Entity with an object a modify it without the need of passing the Entity reference to the EntityManager over and over again.

var entityWrapper = new EntityWrapper(entity)
    .SetComponentData(new Translation { Value = float3.zero });
    .AddBuffer<TaskBufferElement>();
    .AddBuffer(
        new PathPositionBufferElement {position = new int2(0, 1)},
        new PathPositionBufferElement {position = new int2(0, 2)}
    );

You can also specify target entity manager / command buffer when creating a wrapper:

EntityWrapper.Wrap(entity, PostUpdateCommands)
    .AddBuffer<MyBuffer>()
    .SetComponentData(new Translation {Value = command.position})
    .SetComponentData(new Scale {Value = 1.0f});

Creating an entity

Apart of modifying, you can also create the entities using the EntityWrapper:

EntityWrapper.CreateEntity(EntityManager)
    .AddBuffer<MyBuffer>()
    .SetComponentData(new Translation {Value = command.position})
    .SetComponentData(new Scale {Value = 1.0f});

In this case, you pass the EntityManager or a command buffer into the CreateEntity method and the wrapper will do the rest for you.

EntityManagerWrapper

EntityManagerWrapper wraps around different ways of accessing EntityManager:

  1. EntityManager
EntityManagerWrapper.Default
  1. EntityCommandBuffer (PostUpdateCommands)
EntityManagerWrapper.FromCommandBuffer(PostUpdateCommands)
  1. EntityCommandBuffer.Concurrent (Jobs)
EntityManagerWrapper.FromJobCommandBuffer(commandBuffer, threadId);

Usage example:

var entityWrapper = new EntityWrapper(entity);
entityWrapper.UsingWrapper(EntityManagerWrapper.FromCommandBuffer(PostUpdateCommands), wrapper =>
{
    wrapper.AddComponentData(new Rotation());
    wrapper.AddElementToBuffer(new PathPositionBufferElement {position = new int2(2, 0)});
});

Or using the builder:

var entityManagerWrapper = EntityManagerWrapper.FromJobCommandBuffer(commandBuffer, threadId);

UnitTaskBuilder
    .CreateCombined(itemPosition)
    .AddInnerTasks(
        UnitTaskBuilder.CreateInner(new PickUpItemTaskData {itemEntity = itemEntityToPickUp}).Build(entityManagerWrapper),
        UnitTaskBuilder.CreateInner(new PutItemToStorageTaskData {storageEntity = storageEntity}).Build(entityManagerWrapper)
    )
    .Build(entityManagerWrapper);

EntityBuilder

public class ItemBuilder : EntityBuilder<ItemBuilder>
{
    public static ItemBuilder Create(ItemData itemData)
    {
        return new ItemBuilder(itemData);
    }

    protected override ItemBuilder Self => this;

    internal ItemBuilder(ItemData itemData)
    {
        var contentItem = DependencyProvider.Resolve<ContentItemRepository>().GetByKey(itemData.itemId);

        CreateFromArchetype<ArchetypeItem>();
        this.SetSpriteRenderer(contentItem.icon);
        SetVariable(new ZIndexVariable(SpriteLayers.OBJECT));
        SetComponentData(itemData);
        SetComponentData(new Scale {Value = 0.5f});
    }
}

Usage:

var itemEntity = ItemBuilder
    .Create(contentObject.gatheredResource)
    .SetPosition(EntityManager.GetComponentData<Translation>(taskData.objectEntity).Value)
    .Build(PostUpdateCommands);

You can pass the EntityManagerWrapper into the Build() function.

Defining Archetypes

For defining an archetype you can just create a class implementing IArchetypeDescriptor:

public class ArchetypeItem : IArchetypeDescriptor
{
    public string Name => "Item";

    public ComponentType[] Components => new ComponentType[]
    {
        // common
        typeof(LocalToWorld),
        typeof(Translation),
        typeof(Rotation),
        typeof(Scale),

        // rendering
        typeof(MeshRendererData),

        // type-specific
        typeof(TagItem),
        typeof(ObjectData),
        typeof(ItemData)
    };
}

And then to create it inside the builder:

CreateFromArchetype<ArchetypeItem>();

Initialising Archetypes

As you can only create archetypes in main thread by using EntityManager (not possible via EntityCommandBuffer), you can initialise your archetypes beforehand:

EntityArchetypeManager.Instance.InitializeArchetypes(
    // tasks
    typeof(ArchetypeCombinedUnitTask),
    typeof(ArchetypeSingleUnitTask),
    typeof(ArchetypeInnerUnitTask),

    // items
    typeof(ArchetypeItem),

    // zones
    typeof(ArchetypeZone),
    typeof(ArchetypeZoneCell),

    // objects
    typeof(ArchetypeDecoration),
    typeof(ArchetypeBuildingGround),

    // generic
    typeof(ArchetypeGenericObjectWithLocation)
);

Alternatively, you can initialize archetypes by marking those classes with [Archetype] attribute:

[Archetype]
public class ArchetypeZone : IArchetypeDescriptor
{
    public string Name => "Zone";

    public ComponentType[] Components => new ComponentType[]
    {
        ... components ...
    };
}

Then you can initialize archetypes for all the marked classes in this assembly with:

EntityArchetypeManager.Instance.InitializeArchetypes(Assembly.GetCallingAssembly());

Initialising Archetypes in specific worlds

By default all the archetypes will be initialized in World.DefaultGameObjectInjectWorld If you want to change this, you can specify the world by passing World parameter in the Attribute:

[Archetype(WorldType.SERVER)]
public class ServerPlayerArchetype : IArchetypeDescriptor

Extending the EntityWrapper/EntityBuilder

You can easily add your own methods to EntityWrapper:

public static class EntityWrapper2DExtensions
{
    public static void SetPosition2D(this EntityWrapper wrapper, int2 position)
    {
        wrapper.SetComponentData(new Translation {Value = new float3(position.x + 0.5f, position.y + 0.5f, 0)});
    }
}

Or to EntityBuilder:

public static class EntityBuilder2DExtensions
{
    public static T SetPosition2D<T>(this EntityBuilder<T> wrapper, int2 position)
    {
        return wrapper.AddStep(new SetPosition2D(position));
    }
}

public class SetPosition2D : IEntityBuilderStep
{
    private readonly int2 position;

    public SetPosition2D(int2 position)
    {
        this.position = position;
    }

    public void Process(EntityManagerWrapper wrapper, EntityVariableMap variables, ref EntityBuilderData data)
    {
        wrapper.SetComponentData(data.entity, new Translation {Value = new float3(position.x + 0.5f, position.y + 0.5f, 0)});
    }
}

Additional functionality on Build()

To add your own Build implementation and access the EntityManager that was used for building, you can overload a OnBuild method:

public override void OnBuild(EntityManagerWrapper wrapper, Entity dataEntity)
{
    // your building code
}

Mapping GameObjects with the built entity

You can create a game object inside a builder and link it with the created entity without using ConvertToEntity component.

protected override void OnPreBuild(EntityManagerWrapper wrapper)
{
    base.OnPreBuild(wrapper);

    var prefab = ResourceProvider.GetPrefab("Items/Item");
    var gameObject = GameObjectEntityManager.Instance.CreateFromPrefab(prefab);

    AddComponentData(new ManagedGameObject {instanceId = gameObject.GetInstanceID()});
}

Variables

When extending the EntityWrapper you might want to save some data in the wrapper to reuse it in your extensions. For example, when setting the 2D position, you might want to save ZIndex to be used for this exact entity.

public class ZIndexVariable : IEntityVariable
{
    public int zIndex;

    public ZIndexVariable(int zIndex)
    {
        this.zIndex = zIndex;
    }
}

And then extend the EntityBuilder:

public class SetPosition2D : IEntityBuilderStep
{
    private const float ZIndexMultiplier = 0.01f;
    private readonly int2 position;

    public SetPosition2D(int2 position)
    {
        this.position = position;
    }

    private Translation GetTranslation(EntityVariableMap variables)
    {
        var zIndex = variables.Get<ZIndexVariable>()?.zIndex ?? 0;
        return new Translation {Value = new float3(position.x + 0.5f, position.y + 0.5f, -zIndex * ZIndexMultiplier)};
    }

    public void Process(EntityManagerWrapper wrapper, EntityVariableMap variables, ref EntityBuilderData data)
    {
        wrapper.SetComponentData(data.entity, GetTranslation(variables));
    }
}

Usage:

ObjectBuilder.Create(6)
    .SetVariable(new ZIndexVariable(10));
    .SetPosition2D(new int2 {x = -7, y = 0})
    .Build();
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].