Question Regarding Component Tags

Suppose I have a tile game with 2 separate boards and 5 entities on each board. My question is , all the entities will have the same components eg position and a system that process the position component. How do I separate them out so I can process boardA entities from boardB. I know people use empty components to tag compBoardA and compBoardB. But what if I have 100 boards, surly im not suppose to create 100 uniques components with different names ?

If they are completely separated you could set up different Worlds? Personally I would try to figure out a way to make the systems involved work on all of them. If neither one of those are possible, then you need to figure out a way to query for entities owner by each board separately.

Use Board : ISharedComponentData { int boardId } then put SCD filter on EntityQuery to get the chunks of that board

2 Likes

This is great! How did it get past me that you could define query filters on SCD values!? :slight_smile:

Thanks for the replies, let me see if I can get this working

OK I have a question. I have not sue SCD extensively so Im a little confused here. If i change SCD on one board wont it change it on all boards. Also what do mean query filters on SCD values , wont all the values be the same.

Your SCD value would be an int boardID which you set at the start and shouldn’t need to change during game play. Each chunk would have entities with the same boardID value (by default, as they are SCD). So e.g. you can add SCD boardID value = 2 to the entity query and this then only returns chunks with that value.

To better understand this concept I read through 5argon blog post and wrote a simple GameObjectConversionSystem to wrap my head around the concept.

Give the code below how do I query and only returns chunks with that value.

in my scene I have 2 game object in a subScene. Only difference is one is has NumEntities set to 5 and other one has NumberEntities set to 10.

In my conversion I simply create the number entity and add SCD to NumEntities. So I end up with 5 entities all with a SCD value of 5 and 10 entities with a SCD of 10

sorry it’s an image I lost internet so writing this from my phone :frowning:

Thanks for the help

5359614--541878--A3014192-6E20-4E94-9392-59F260562A06.jpeg

I’m not sure on the syntax when using ForEach, but here are the docs for the SCD filter if you haven’t seen it already.
https://docs.unity3d.com/Packages/com.unity.entities@0.4/manual/ecs_entity_query.html

https://docs.unity3d.com/Packages/com.unity.entities@0.4/manual/entities_job_foreach.html#shared-component-filtering

1 Like

Interesting, I have not seen these docs. Excited to try this out , thanks everyone

Thank for the link, I was looking at the code snippet and was confused how the NativeList dependencies was suppose to work. I made a simple example from the code below to try and understand but I get InvalidOperationException:

The NativeArray has been deallocated, it is not allowed to access it @ dependencies.Add(thisJobHandle);

ORIGINAL

public class ColorCycleJob : JobComponentSystem
{
   protected override JobHandle OnUpdate(JobHandle inputDeps)
   {
       List<Cohort> cohorts = new List<Cohort>();
       EntityManager.GetAllUniqueSharedComponentData<Cohort>(cohorts);
       NativeList<JobHandle> dependencies
           = new NativeList<JobHandle>();

       foreach (Cohort cohort in cohorts)
       {
           DisplayColor newColor = ColorTable.GetNextColor(cohort.Value);
           JobHandle thisJobHandle
               = Entities.WithSharedComponentFilter(cohort)
                   .ForEach((ref DisplayColor color) => { color = newColor; })
                   .Schedule(inputDeps);
           dependencies.Add(thisJobHandle); // InvalidOperationException The NativeArray has been deallocated, it is not allowed to access it
       }

       return JobHandle.CombineDependencies(dependencies);
   }
}

SIMPLE EXAMPLE NO DEPENDANCIES

protected override JobHandle OnUpdate(JobHandle inputDeps)
{
    // TODO : investigate passing EntityQuery to Schedule()

    //
    // API 0.4.0 updating inputDeps = new SetData().Schedule(_qEntityData, inputDeps);
    inputDeps = Entities.ForEach((ref EntityDataComponent c) => { c.EntityData = 11; }).Schedule(inputDeps);
    inputDeps.Complete();

    //
    // Update by SCD 
    List<EntityIdComponent> ids = new List<EntityIdComponent>();
    EntityManager.GetAllUniqueSharedComponentData<EntityIdComponent>(ids);
    foreach (EntityIdComponent id in ids)
    {
        if( id.EntityId == 1) continue;
        JobHandle thisJobHandle
            = Entities.WithSharedComponentFilter(id)
                .ForEach((ref EntityDataComponent data) => { data.EntityData = 99; })
                .Schedule(inputDeps);

        thisJobHandle.Complete();
    }

    //
    // TODO : EntityManager.DestroyEntity(_qEntityData);
    return inputDeps;

Removing dependencies it works like I expect but I would like to understand the whole dependencies.Add(thisJobHandle). Any help or resources I would be gratfull for

Unfortunately that snippet from the docs doesn’t actually run. In this thread I got confirmation from a Unity person that the example does not work as written, and it will be changed. You can accomplish what the example is trying to demonstrate by disabling the safety system, so long as you know what you’re doing. You can read that thread for details.

I’m not sure why you would be getting a “Deallocated” error from your first example. I can only assume you’re parsing the wrong exception and the deallocation part is a symptom of some earlier error.

Edit: Just realized, you aren’t actually allocating the list. You need to pass in an allocator:
var list = new NativeList(Allocator.TempJob). The example still won’t work as written though.

Ok good to know.

Sorry should have just put the whole trace

InvalidOperationException: The NativeArray has been deallocated, it is not allowed to access it
Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle.CheckWriteAndBumpSecondaryVersion (Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle handle) <0x17c90caa0 + 0x00052> in <ad86e8e508c54768abd7c1fb9256ddc2>:0
Unity.Collections.NativeList`1[T].Add (T value) (at Library/PackageCache/com.unity.collections@0.4.0-preview.6/Unity.Collections/NativeList.cs:220)
SimpleSubScene.Systems.ColorCycleJob.OnUpdate (Unity.Jobs.JobHandle inputDeps) (at Assets/SimpleSubScene/Systems/ColorCycleJob.cs:27)
Unity.Entities.JobComponentSystem.Update () (at Library/PackageCache/com.unity.entities@0.4.0-preview.10/Unity.Entities/JobComponentSystem.cs:129)
Unity.Entities.ComponentSystemGroup.UpdateAllSystems () (at Library/PackageCache/com.unity.entities@0.4.0-preview.10/Unity.Entities/ComponentSystemGroup.cs:182)
UnityEngine.Debug:LogException(Exception)
Unity.Debug:LogException(Exception) (at Library/PackageCache/com.unity.entities@0.4.0-preview.10/Unity.Entities/Stubs/Unity/Debug.cs:19)
Unity.Entities.ComponentSystemGroup:UpdateAllSystems() (at Library/PackageCache/com.unity.entities@0.4.0-preview.10/Unity.Entities/ComponentSystemGroup.cs:186)
Unity.Entities.ComponentSystemGroup:OnUpdate() (at Library/PackageCache/com.unity.entities@0.4.0-preview.10/Unity.Entities/ComponentSystemGroup.cs:169)
Unity.Entities.ComponentSystem:Update() (at Library/PackageCache/com.unity.entities@0.4.0-preview.10/Unity.Entities/ComponentSystem.cs:107)
Unity.Entities.DummyDelegateWrapper:TriggerUpdate() (at Library/PackageCache/com.unity.entities@0.4.0-preview.10/Unity.Entities/ScriptBehaviourUpdateOrder.cs:152)
InvalidOperationException: The previously scheduled job ColorCycleJob:<>c__DisplayClass_OnUpdate_LambdaJob0 writes to the NativeArray <>c__DisplayClass_OnUpdate_LambdaJob0.Data._lambdaParameterValueProviders.forParameter0._type. You are trying to schedule a new job ColorCycleJob:<>c__DisplayClass_OnUpdate_LambdaJob0, which writes to the same NativeArray (via <>c__DisplayClass_OnUpdate_LambdaJob0.Data._lambdaParameterValueProviders.forParameter0._type). To guarantee safety, you must include ColorCycleJob:<>c__DisplayClass_OnUpdate_La
Unity.Entities.JobChunkExtensions.ScheduleInternal[T] (T& jobData, Unity.Entities.EntityQuery query, Unity.Jobs.JobHandle dependsOn, Unity.Jobs.LowLevel.Unsafe.ScheduleMode mode) (at Library/PackageCache/com.unity.entities@0.4.0-preview.10/Unity.Entities/IJobChunk.cs:170)
Unity.Entities.JobChunkExtensions.Schedule[T] (T jobData, Unity.Entities.EntityQuery query, Unity.Jobs.JobHandle dependsOn) (at Library/PackageCache/com.unity.entities@0.4.0-preview.10/Unity.Entities/IJobChunk.cs:86)
SimpleSubScene.Systems.ColorCycleJob.OnUpdate (Unity.Jobs.JobHandle inputDeps) (at Assets/SimpleSubScene/Systems/ColorCycleJob.cs:23)
Unity.Entities.JobComponentSystem.Update () (at Library/PackageCache/com.unity.entities@0.4.0-preview.10/Unity.Entities/JobComponentSystem.cs:129)
Unity.Entities.ComponentSystemGroup.UpdateAllSystems () (at Library/PackageCache/com.unity.entities@0.4.0-preview.10/Unity.Entities/ComponentSystemGroup.cs:182)
UnityEngine.Debug:LogException(Exception)
Unity.Debug:LogException(Exception) (at Library/PackageCache/com.unity.entities@0.4.0-preview.10/Unity.Entities/Stubs/Unity/Debug.cs:19)
Unity.Entities.ComponentSystemGroup:UpdateAllSystems() (at Library/PackageCache/com.unity.entities@0.4.0-preview.10/Unity.Entities/ComponentSystemGroup.cs:186)
Unity.Entities.ComponentSystemGroup:OnUpdate() (at Library/PackageCache/com.unity.entities@0.4.0-preview.10/Unity.Entities/ComponentSystemGroup.cs:169)
Unity.Entities.ComponentSystem:Update() (at Library/PackageCache/com.unity.entities@0.4.0-preview.10/Unity.Entities/ComponentSystem.cs:107)
Unity.Entities.DummyDelegateWrapper:TriggerUpdate() (at Library/PackageCache/com.unity.entities@0.4.0-preview.10/Unity.Entities/ScriptBehaviourUpdateOrder.cs:152)
using System.Collections.Generic;
using SimpleSubScene.Components;
using SimpleSubScene.Proxies;
using Unity.Collections;
using Unity.Entities;
using Unity.Jobs;
using UnityEngine;

namespace SimpleSubScene.Systems
{
    public class ColorCycleJob : JobComponentSystem
    {
        protected override JobHandle OnUpdate(JobHandle inputDeps)
        {
            List<EntityIdComponent> cohorts = new List<EntityIdComponent>();
            EntityManager.GetAllUniqueSharedComponentData<EntityIdComponent>(cohorts);
            NativeList<JobHandle> dependencies
                = new NativeList<JobHandle>();

            foreach (EntityIdComponent cohort in cohorts)
            {
                //DisplayColor newColor = ColorTable.GetNextColor(cohort.Value);
                JobHandle thisJobHandle
                    = Entities.WithSharedComponentFilter(cohort)
                        .ForEach((ref EntityDataComponent color) => { color.EntityData = 55; })
                        .Schedule(inputDeps);
                dependencies.Add(thisJobHandle);
            }

            return JobHandle.CombineDependencies(dependencies);
        }
    }
}

Sorry, I edited my original post, must have done as you were posting that:

Ahh yup, thank you