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.

Instantiating Prefab with dynamic physics results in...missing prefab.

Discussion in 'Physics for ECS' started by ChristopherWathen, Sep 11, 2020.

  1. ChristopherWathen


    Dec 24, 2019
    I'm attempting to create a shattering effect by replacing a prefab at runtime with a shattered version of the prefab where each of its chunks has a physics body and physics shape. When I have the motion type set to static the prefab swaps out and everything looks great. As soon as I turn dynamic on the chunks the original prefab will disappear but I see nothing replace it. I kept all of the chunks but one as static and it is replacing the original prefab just fine but the one chunk set to dynamic is missing and nowhere to be found. I'm not seeing any errors but if I perform this action multiple times the frame rate drops dramatically and eventually Unity locks up.

    When testing the shattered prefab in a clean environment everything works fine and the physics simulation plays out like you would expect. This however is not spawning it at runtime just adding the physics components and using the Convert To Entity method. I've been fiddling with it for hours at this point and I'm at a loss. Here is the code snippet.

    Also: I am on the latest version of the Unity Physics package.

    Code (CSharp):
    2. var ecb = _commandBufferSystem.CreateCommandBuffer();
    4.             var shatteredPrefab = EntityManager
    5.                 .GetComponentData<ShatteredPrefabComponent>(GetSingletonEntity<ShatteredPrefabComponent>()).Value;
    7.             Entities.WithAny<ToSelectComponent>().ForEach(
    8.                 (Entity e,  int entityInQueryIndex, ref CellCoordinatesComponent cellCoordinates, ref Translation translation) =>
    9.                 {
    10.                     var shatteredEntity = ecb.Instantiate(shatteredPrefab);
    11.                     ecb.SetComponent(shatteredEntity, translation);
    14.                     ecb.DestroyEntity(e);
    16.                 }).Schedule();
    18.             _commandBufferSystem.AddJobHandleForProducer(this.Dependency);

    UPDATE: So it appears the issue is related to the children of the prefab becoming unparented due to the physics simulation and therefore not moving to the correct location because I'm only updating the parent translation. Which now begs the there a reasonable way to translate the chunks so that they line up as they would have in local space with the original parent prefab?
    Last edited: Sep 11, 2020
  2. ChristopherWathen


    Dec 24, 2019
    I've made some progress on this. I'm instantiating the shatter prefab with just a static body and a flag on each of the chunks. I then set the shattered prefab to the position of the original prefab. The system below just adds the basic physics components to each of the chunks after they have spawned. The shatter prefab replaces the original one just fine and gravity and velocity work but the chunks just fall through the rest of the physics objects in the world. If it do this same exact process with just a single chunk not parented it works fine and the single junk collides with the rest of the objects. At this point I may just resort to storing the local offset on each of the chunks and just bring them in individually and apply the offset position to them and see what happens.

    Code (CSharp):
    1. using Sources.Components.Authoring;
    2. using Sources.Components.Rendering.HexGrid;
    3. using Sources.Components.Selection;
    4. using Unity.Entities;
    5. using Unity.Mathematics;
    6. using Unity.Physics;
    7. using Unity.Physics.Systems;
    8. using Unity.Transforms;
    11. namespace Sources.Systems.Selection
    12. {
    13.     public class AddPhysicsToChunksSystem : SystemBase
    14.     {
    15.         private EndSimulationEntityCommandBufferSystem _commandBufferSystem;
    18.         protected override void OnCreate()
    19.         {
    20.             _commandBufferSystem = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>();
    21.         }
    23.         protected override void OnUpdate()
    24.         {
    25.             var ecb = _commandBufferSystem.CreateCommandBuffer();
    28.             Entities.WithoutBurst().WithAny<ChildChunkComponent>().ForEach(
    29.                 (Entity e, int entityInQueryIndex, ref PhysicsCollider collider) =>
    30.                 {
    31.                     ecb.AddComponent(e, PhysicsMass.CreateDynamic(collider.MassProperties, 1));
    33.                     ecb.AddComponent(e, new PhysicsVelocity()
    34.                     {
    35.                         Linear = new float3(0,3,0),
    36.                         Angular =
    37.                     });
    38.                     ecb.AddComponent(e, new PhysicsDamping()
    39.                     {
    40.                         Linear = 0.01f,
    41.                         Angular = 0.05f
    42.                     });
    44.                     ecb.RemoveComponent<ChildChunkComponent>(e);
    45.                 }).Schedule();
    47.             _commandBufferSystem.AddJobHandleForProducer(this.Dependency);
    48.         }
    49.     }
    50. }
  3. steveeHavok


    Mar 19, 2019
    Any chance of getting a small repro scene in the Samples project I could play with?