sschmid / Entitas

Entitas is a super fast Entity Component System (ECS) Framework specifically made for C# and Unity
MIT License
7.16k stars 1.11k forks source link

Unique component not working? #897

Closed Shivang44 closed 5 years ago

Shivang44 commented 5 years ago

I created a MainPlayerComponent so I can have an singleton entity that acts as the main player:

using Entitas;
using UnityEngine;
using Entitas.CodeGeneration.Attributes;

[Game]
[Unique]
public sealed class MainPlayerComponent : IComponent
{
}

The issue I'm having is that after creating an entity with this component like this:

    public void Initialize()
    {
        var e = this.context.CreateEntity();
        e.AddRender("Player");
        e.AddPosition(new Vector3Int(0,0,0));   
        e.isMainPlayer = true;
    }

I can't access the above created singleton Entity. In another Execute system, this returns null (the context is the Game context the component is part of above):

Debug.Log(context.mainPlayerEntity);

Any idea why this is null? The entity is created. I can see in the Unity Inspector that it has the MainPlayer component attached. Another (I think related) issue is that this [Unique] attribute it supposed to make it so I can't create multiple entities with this component attach, but I'm able to do so. This doesn't throw an error:

    public void Initialize()
    {
        var e = this.context.CreateEntity();
        e.AddRender("Player");
        e.AddPosition(new Vector3Int(0,0,0));   
        e.isMainPlayer = true;

        var ez = this.context.CreateEntity();
        ez.AddRender("Player");
        ez.AddPosition(new Vector3Int(0,0,0));
        ez.isMainPlayer = true;
    }

The [Unique] attribute sounds really awesome, but it's just not working for me at all. I'm unable to access the Unique entity with this component attached with context.entity, and I'm able to create multiple entitas with this component attached. I'm using Entitas 1.13.0. Really loving Entitas so far, would love any help on this issue! Thanks

Shivang44 commented 5 years ago

I found a work around. If the [Unique] component has a public field, like this:

using UnityEngine;
using Entitas.CodeGeneration.Attributes;

[Game]
[Unique]
public sealed class MainPlayerComponent : IComponent
{
    public string username;
}

Then the code generator generates a "SetMainPlayer" method, which I can call to create this unique entity:

        this.context.SetMainPlayer("test");
        this.context.mainPlayerEntity.AddRender("Player");
        this.context.mainPlayerEntity.AddPosition(new Vector3Int());

And everything works like normal. However if the [Unique] component has no fields, and I just want it to be a boolean component like "isMainPlayer", there is no SetMainPlayer method and I don't know how to create this unique entity (since CreateEntity and .isMainPlayer=true doesn't work as posted in the OP).

Please let me know if this is a bug or I'm doing something incorrectly. Basically, how can I create a unique entity with no public fields?

Thanks!

Shivang44 commented 5 years ago

Thanks to @JesseTG from the Entitas Gitter, I learned that you have to actually do

this.context.isMainPlayer = true

first to create the unique entity. Then I can add any other components I need. It works now!