Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Join us on Dec 8, 2022, between 7 am & 7 pm EST, in the DOTS Dev Blitz Day 2022 - Q&A forum, Discord, and Unity3D Subreddit to learn more about DOTS directly from the Unity Developers.
    Dismiss Notice
  3. Have a look at our Games Focus blog post series which will show what Unity is doing for all game developers – now, next year, and in the future.
    Dismiss Notice

Resolved Set Collider during runtime

Discussion in 'DOTS Physics' started by slushieboy99, Sep 6, 2021.

  1. slushieboy99


    Aug 29, 2014
    I'm trying to set collider data on a single entity but I get the error "InvalidOperationException: Adding/removing components or changing position/rotation/velocity/collider ECS data on dynamic entities during physics step".
    I looked through the example at, but I only need to update component data for one entity at a time, so I'd rather not create an entire new systembase class for that. Is there any way to schedule a specific function to run when a physics step is not? Below is my code:

    Code (CSharp):
    1. entityManager.SetComponentData(meshEntity, new PhysicsCollider {
    2.             Value = output[0]
    3.         });
    Where output[0] is a physicscollider blobassetreference.
  2. steveeHavok


    Mar 19, 2019
    The problem is that the
    use the same Entity Query to get the physics related entities. If you change data yourself between these systems then the order of entities could be different and the export writes the data into incorrect components, or you make changes to the ECS data and the export overwrites you changes.

    Instead of setting the
    directly, you could create an
    from the
    and have the data set after the fixed step has complete.
    slushieboy99 likes this.
  3. slushieboy99


    Aug 29, 2014
    My understanding is that command buffers can only be used in a System. I was hoping to find a solution where I don't need to create any systems.
  4. slushieboy99


    Aug 29, 2014
    Okay so I've gone ahead and tried to set the physics collider in a system, but I'm still getting lots of the same errors.

    Code (CSharp):
    1. using PCollider = Unity.Entities.BlobAssetReference<Unity.Physics.Collider>;
    3. public struct PhysicsColliderHolder : IComponentData { public PCollider held; }
    5. [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    6. [UpdateBefore(typeof(BuildPhysicsWorld))]
    7. public class ApplyMeshColliderJobSystem : SystemBase {
    8.     protected override void OnUpdate() {
    9.         using (var commandBuffer = new EndFixedStepSimulationEntityCommandBufferSystem().CreateCommandBuffer()) {
    10.             Entities
    11.             .WithName("terrain_chunk")
    12.             .ForEach((Entity entity, ref PhysicsColliderHolder holder) => {
    13.                 PhysicsCollider collider = new PhysicsCollider() {
    14.                     Value = holder.held
    15.                 };
    16.                 commandBuffer.SetComponent(entity, collider);
    17.                 commandBuffer.RemoveComponent(entity, typeof(PhysicsColliderHolder));
    18.             }).Run();
    19.             commandBuffer.Playback(EntityManager);
    20.         }
    21.     }
    22. }
    I'm also getting an Object Reference Not Set to Instance of Object error at
    var world = World.Unmanaged;
    in EntityCommandBufferSystem.CreateCommandBuffer();

    I can't find any examples of someone trying to set a collider at runtime, except for the example above which seems to just swap two existing collider. I tried directly modifying that code and it did not work so I'm a little lost here. If anyone has examples I can look at for how to do this properly that would be really helpful.

    I also can't seem to add a
    to an entity even if it's not in a PhysicsCollider struct. As you can see, I tried to add a new component
    public struct PhysicsColliderHolder : IComponentData { public PCollider held; }
    to get the generated collider into the system, but when I add this component to an entity I get the same physics step error. So on top of all this, I have no idea how to actually get the collider I want to add to an entity into the system, it's quite the conundrum haha.
    Last edited: Sep 10, 2021
  5. slushieboy99


    Aug 29, 2014
    Alternatively, when I try to do the same thing outside of a system, I get all the same errors:

    Code (CSharp):
    1. EntityCommandBuffer commandBuffer = new EndFixedStepSimulationEntityCommandBufferSystem().CreateCommandBuffer();
    2.         PhysicsCollider collider = new PhysicsCollider { Value = output[0] };
    3.         commandBuffer.SetComponent(meshEntity, collider);
    4.         commandBuffer.Playback(entityManager);
    This is ideally what I'd like my code to be as it is much simpler for this solution than a System, but I still get the null object reference on World.Unmanaged and my console is still spammed with Physics Step errors.
  6. slushieboy99


    Aug 29, 2014
    Okay after some more research I got this working.

    Code (CSharp):
    1. PhysicsCollider collider = new PhysicsCollider { Value = output[0] };
    2.         EntityCommandBufferSystem ecbSystem = World.DefaultGameObjectInjectionWorld.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>();
    3.         EntityCommandBuffer buffer = ecbSystem.CreateCommandBuffer();
    4.         buffer.SetComponent(meshEntity, collider);
    A few notes as an aside, many of the docs on EntityBufferSystems seem to be outdated. I messed around with EntityCommandBufferSystem.PostUpdateCommands a lot which only seemed to lead to EntityCommandBuffer not initialized errors, but I'm curious if anyone knows how to currently use this as it's seemingly different than it is in the documentation.