Search Unity

Cannot access two ISharedComponent in Entities.Foreach(ISharedComponentA,ISharedComponentB)

Discussion in 'Entity Component System' started by ChromeCat, Jun 29, 2019.

  1. ChromeCat

    ChromeCat

    Joined:
    Jan 27, 2016
    Posts:
    35
    As I described in the title, I cannot use Foreach to access two ISharedComponent.

    I've looked the file EntityQueryBuilder which Foreach is declared, and it seems Foreach was made by tons of generic functions. But there was no matching generic function that supports two ISharedComponent.

    Is there any alternative to Foreach?
     
  2. digitaliliad

    digitaliliad

    Joined:
    Jul 1, 2018
    Posts:
    64
  3. Enzi

    Enzi

    Joined:
    Jan 28, 2013
    Posts:
    962
    If you can tell us what data you have in the 2 SharedComponent we can help further.

    I asked the same question once and the answer is, chunks only have one SharedComponent unless it can be shared and are equal. Design with more than 1 SharedComponentData is usually against ECS unless you have a very specific use-case, I can't think of any that can't be brought into a single SharedComponent.

    SCDs are a weird one and easily abused, I know I did with my first ECS project. Monobehaviours can be accessed without the use of SCDs and for everything that's a collection, DynamicBuffers should be used.

    https://docs.unity3d.com/Packages/com.unity.entities@0.0/manual/shared_component_data.html
     
  4. ChromeCat

    ChromeCat

    Joined:
    Jan 27, 2016
    Posts:
    35
    Yes. I'm using hybrid ecs approach, so I have some reference to Monobehaviour objects in SharedComponent.

    When I add sharedComponent PrefabAssetComponent(which holds prefab) to entity, system creates prefab instances and create PrefabInstanceComponent(ISystemSharedComponent) to hold that instance.

    And when I add BehaviourTreeAssetComponent to entity, system does follows.
    Code (CSharp):
    1. Entities.WithAll<PrefabInstanceComponent,BehaviourTreeAssetComponent>().Foreach((Entity e,PrefabInstanceComponent instData, BehaviourTreeAssetComponent btAsset)=>{
    2.   var btOwner = instData.gameObject.AddComponent<BTOwner>();
    3.   btOwner.tree = btAsset.treeAsset;
    4.   PostUpdateCommand.AddSharedComponent(e,new BTOwner
    5. {
    6.   owner = btOwner
    7. });
    8. });
    BTOwner is just MonoBehaviour and I need system to be add component when both PrefabInstanceComponent and BehaviourTreeAssetComponent are attached.

    I know in pure ECS it's not a good way to do this stuff, but I had to use animations or other AI plugins, so I had no choice.
     
  5. Enzi

    Enzi

    Joined:
    Jan 28, 2013
    Posts:
    962
    I'd say you have overcomplicated the problem and I don't think you really need these data transformations. Take a look at my hybrid ECS animation system. It's barebones and works on hybrid and serves as a bridge with minimal setup.

    It builds a cached version of entities and Animators and the Animators can be used like you know them from basic Unity with an AnimationEvent comp that has data what should happen.
    If you don't find it useful, the method to get the monobehaviour in a system should still be interesting to you.
     

    Attached Files:

    ChromeCat likes this.
  6. ChromeCat

    ChromeCat

    Joined:
    Jan 27, 2016
    Posts:
    35
    Whoa I didn't know GetComponentObject can get the reference type component from entity. And it's good idea to match id with animationName string.

    Thanks! I'll give it a try