Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

ArgumentException: The EntityArchetype was not created by this EntityManager

Discussion in 'Entity Component System' started by florianhanke, Jan 17, 2020.

  1. florianhanke

    florianhanke

    Joined:
    Jun 8, 2018
    Posts:
    426
    Hi all!

    I've just upgraded to Entities 0.5.0-preview.17, and now I am running into a
    ArgumentException: The EntityArchetype was not created by this EntityManager
    .

    Full error:

    Code (CSharp):
    1. ArgumentException: The EntityArchetype was not created by this EntityManager
    2. EntityCommandBuffer was recorded in FiringJobSystem and played back in Unity.Entities.EndSimulationEntityCommandBufferSystem.
    In the below
    FiringJobSystem
    , I am getting a
    projectileRequestArchetype
    , which is just an entity archetype that I have cached and am trying to reuse that signals my
    SpawnSystem
    to create a projectile.

    In the
    OnUpdate
    , I am then trying to use
    commandBuffer.CreateEntity
    with the archetype to generate a
    ProjectileRequest
    entity from the archetype.

    I do not understand the error – yes, the archetype was not generated by the
    commandBuffer
    , since I cache it in another system. How can I cache the archetype, then? Do I have a fundamental misunderstanding of how archetypes or EntityManagers should be used or do I just have a silly error in the code below?

    Code (CSharp):
    1. public class FiringJobSystem : JobComponentSystem
    2. {
    3.     // EndFrameBarrier provides the CommandBuffer
    4.     EntityCommandBufferSystem barrier;
    5.  
    6.     protected override void OnCreate()
    7.     {
    8.         base.OnCreate();
    9.  
    10.         // Cache the EndFrameBarrier in a field, so we don't have to get it every frame.
    11.         barrier = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>();
    12.     }
    13.  
    14.     [BurstCompile]
    15.     protected override JobHandle OnUpdate(JobHandle inputDeps)
    16.     {
    17.         var dt = Time.DeltaTime;
    18.         var projectileRequestArchetype = Archetypes.Spawn(EntityManager, typeof(ProjectileRequest));
    19.         var commandBuffer = barrier.CreateCommandBuffer().ToConcurrent();
    20.         var handle = Entities
    21.             .ForEach(
    22.                 (Entity entity,
    23.                     int entityInQueryIndex,
    24.                     ref Weapon weapon,
    25.                     ref WeaponCooldown weaponCooldown,
    26.                     ref LocalToWorld ltw) =>
    27.                 {
    28.                     if (weaponCooldown.seconds <= 0) {
    29.                         // Creates a projectile in the SpawnSystem.
    30.                         var projectileRequestEntity = commandBuffer.CreateEntity(entityInQueryIndex, projectileRequestArchetype);
    31.                         var translation = ltw.Position + ltw.Forward * 2f;
    32.                         var target      = translation + ltw.Forward;
    33.                         commandBuffer.SetComponent(entityInQueryIndex, projectileRequestEntity, new ProjectileRequest {
    34.                             translation = new Translation { Value = translation },
    35.                             target = new Translation { Value = target },
    36.                             speed = 500f,
    37.                         });
    38.                     }
    39.  
    40.                     // Reset the cooldown timer.
    41.                     weaponCooldown.seconds = weapon.secondsCooldown;
    42.                 }).Schedule(inputDeps);
    43.         barrier.AddJobHandleForProducer(handle);
    44.         return handle;
    45.     }
    46. }
    Many thanks in advance for any help!
     
  2. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,683
    Show your Archetypes.Spawn implementation
     
  3. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    I think most likely you are caching an Archetype from another world (Maybe as a static variable?) and this new check found a bug in your code.
     
  4. florianhanke

    florianhanke

    Joined:
    Jun 8, 2018
    Posts:
    426
    Thanks for your answers!

    The Archetypes.Spawn implementation is rather old, and part of the issue is indeed as @Joachim_Ante guesses that I use a static instead of a per-spawn system cache (better: have an Archetypes instance on the SpawnSystem).

    Code (CSharp):
    1.         static private Dictionary<ComponentType, EntityArchetype> spawnArchetypes = new Dictionary<ComponentType, EntityArchetype>();
    2.  
    3.         internal static EntityArchetype Spawn(EntityManager manager, ComponentType type)
    4.         {
    5.             EntityArchetype entityArchetype;
    6.             spawnArchetypes.TryGetValue(type, out entityArchetype);
    7.  
    8.             Debug.Log("Entity Manager: " + manager.World);
    9.  
    10.             if (entityArchetype.Valid) {
    11.                 return entityArchetype;
    12.             } else {
    13.                 var entityArchetypeToInsert = manager.CreateArchetype(typeof(Spawn), type);
    14.                 spawnArchetypes.Add(type, entityArchetypeToInsert);
    15.                 return entityArchetypeToInsert;
    16.             }
    17.         }
    The second half of the issue is that I am running NetCode (which I forgot to mention, I'm afraid). For some reason I assumed that the Server would run in a separate process, but for ease of development, it does not in play mode, so in combination with the static dictionary this turns out to be an issue, as the dict is shared by Client and Server world.

    The output of
    Debug.Log("Entity Manager: " + manager.World);
    by the way is:
    Screenshot 2020-01-19 19.08.15.png
    So the ClientWorld0 is first in storing the value, and further down:
    Screenshot 2020-01-19 19.08.23.png

    So, thanks again.

    A feedback: I would have immediately noticed the issue if the error message would have contained the entity manager's World, such as
    The EntityArchetype was not created by this EntityManager (ServerWorld)
    . So that maybe helps avoid future posts.