Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

DOTS Physics crashed in RayCasting when spawning entities

Discussion in 'Physics Previews' started by microwest, Apr 16, 2019.

  1. microwest

    microwest

    Joined:
    Aug 27, 2013
    Posts:
    4
    I've been puzzled by this error for days. When i put physics entities in the hierarchy and execute rayCasting in a JobComponentSystem, everything works fine:). But when i spawned the same entities in runtime, the rayCasting JobSystem crashed. No compilation errors, just running crashed.:confused:

    crashed.JPG



    1. Spawning entities can be anywhere and here it's in a ComponentSystem.​
    void SpawnEntities(int count)
    {
    Entity entity;
    Vector2 circle;

    Entity EntityPrefab = GameObjectConversionUtility.ConvertGameObjectHierarchy(playerPrefab, World.Active);

    for (int i = 0; i < count; i++)
    {
    entity = PostUpdateCommands.Instantiate(EntityPrefab);
    circle = Random.insideUnitCircle * Range;

    Translation pos = new Translation()
    {
    Value = new float3(circle.x, 1, circle.y)
    };
    RayCastMove move = new RayCastMove()
    {
    targetPos = pos.Value,
    isHit = 0
    };

    PostUpdateCommands.SetComponent(entity, pos);
    PostUpdateCommands.SetComponent(entity, move);
    } PostUpdateCommands.DestroyEntity(EntityPrefab);
    }

    2. RayCasting is put in a JobComponentSystem.​
    [UpdateAfter(typeof(SpawnSystem))]
    public class RayCastSystem : JobComponentSystem
    {
    [BurstCompile]
    struct RayCastJob : IJobProcessComponentData<Translation, Rotation, RayCastMove>
    {
    [ReadOnly] public PhysicsWorld World;
    public void Execute([ReadOnly] ref Translation pos, [ReadOnly] ref Rotation rot, ref RayCastMove move)
    {
    float3 dirNormal = Math.normalize(Math.mul(rot.Value, new float3(0, 0, 1)));
    RaycastInput input = new RaycastInput()
    {
    Ray = new Ray()
    {
    Origin = pos.Value + dirNormal,
    Direction = dirNormal * 1.1f
    },
    Filter = new CollisionFilter()
    {
    CategoryBits = ~0u, // all 1s, so all layers, collide with everything
    MaskBits = ~0u,
    GroupIndex = 0
    }
    };
    RaycastHit hit = new RaycastHit();
    if (World.CastRay(input, out hit))
    {
    move.isHit = 1;
    }
    else
    move.isHit = 0;
    }
    }
    ... ....
    ... ....
    ... ....
    }

    • Editor console shows that : o_O
    The previously scheduled job RayCastSystem:RayCastJob reads from the NativeArray RayCastJob.Data.World.CollisionWorld.m_Bodies. You must call JobHandle.Complete() on the job RayCastSystem:RayCastJob, before you can deallocate the NativeArray safely.

    So i think when spawning physics entities, the BuildPhysicsWorld system should rebuild the dynamic bodies array and other stuff. But the raycast job conflicts with this. Is that true?:cool:

    and i did a little trick of delaying one frame to schedule the RayCastJob if spawning happened in this frame.:p

    void SpawnEntities(int count)
    {
    isSpawn = true;
    ... ...
    }
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
    ref bool isSpawn = ref World.Active.GetExistingManager<SpawnSystem>().isSpawn;
    if(isSpawn)
    {
    isSpawn = false;
    return inputDeps;
    }
    ... ...
    }

    Now things work like a charm.:D:p

    work.JPG

    • Questions:
    I hope DOTS Physics team will take note of this. Although my own tricks can fix it, is there should be an official way to update physics parameters when entities changed, without crashing other systems?

    As i know, adding or destroying entities in ECS by PostUpdateCommands will not disturb other correlated systems.​

    Or i used the DOTS physics the wrong way?o_O Let me know it.:)
     
    Last edited: Apr 16, 2019
    MasoInar and rizu like this.
  2. rizu

    rizu

    Joined:
    Oct 8, 2013
    Posts:
    1,174
  3. microwest

    microwest

    Joined:
    Aug 27, 2013
    Posts:
    4
    Thanks for your advice. I just post this to the Physics Discussion thread. Hope DOTS will notice.