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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Runtime switch between dynamic and static

Discussion in 'Physics for ECS' started by GilCat, Apr 28, 2020.

  1. GilCat

    GilCat

    Joined:
    Sep 21, 2013
    Posts:
    676
    What is the best approach for switching between a dynamic body to a static body back and forward in runtime?
    Is there any easier way than add/remove PhysicsVelocity, PhysicsMass and PhysicsDamping? Maybe a component that i'm missing that will filter out the entity from being processed by such systems.

    Thank you
     
  2. Rory_Havok

    Rory_Havok

    Joined:
    Jun 25, 2018
    Posts:
    70
    You can just add/remove the PhysicsVelocity and leave the PhysicsMass and PhysicsDamping there, they have no effect while static. How do you rate that versus a new component to force a given motion type?
     
    GilCat likes this.
  3. GilCat

    GilCat

    Joined:
    Sep 21, 2013
    Posts:
    676
    Removing components is fine to me but having a new component (tag) eg. PhysicsStatic, PhysicsKinematic and so on would be more intuitive.

    I've ended up switching my bodies between kinematic and Dynamic. For that i'm adding removing PhysicsGravityFactor instead. It seems to work so i assume it is enough.

    EDITED: Seems that i also need to reset PhysicsMass. That leads me to having a double buffer for it because i want to restore old values every time i go to dynamic motion.

    Thanks
     
    Last edited: Apr 28, 2020
  4. GilCat

    GilCat

    Joined:
    Sep 21, 2013
    Posts:
    676
    I ended up with something like this to control the motion type.

    Code (CSharp):
    1. public struct PhysicsMotionType : IComponentData {
    2.   public BodyMotionType Value;
    3. }
    4.  
    5. public class PhysicsMotionConvertionSystem : GameObjectConversionSystem {
    6.   protected override void OnUpdate() {
    7.     Entities
    8.       .ForEach((PhysicsBodyAuthoring body) => {
    9.         var entity = GetPrimaryEntity(body.gameObject);
    10.         DstEntityManager.AddComponentData(entity,
    11.           new PhysicsMotionType { Value = body.MotionType });
    12.       });
    13.   }
    14. }
    15.  
    16. public class PhysicsMotionTypeSystem : SystemBase {
    17.  
    18.   BeginInitializationEntityCommandBufferSystem m_entityCommandBufferSystem;
    19.   protected override void OnCreate() {
    20.     base.OnCreate();
    21.     m_entityCommandBufferSystem = World.GetOrCreateSystem<BeginInitializationEntityCommandBufferSystem>();
    22.   }
    23.  
    24.   protected override void OnUpdate() {
    25.     var cmdBuffer = m_entityCommandBufferSystem.CreateCommandBuffer().ToConcurrent();
    26.     Entities
    27.       .WithChangeFilter<PhysicsMotionType>()
    28.       .ForEach((Entity entity, int entityInQueryIndex, in PhysicsMotionType motionType) => {
    29.         if (motionType.Value == BodyMotionType.Static)
    30.           cmdBuffer.RemoveComponent<PhysicsVelocity>(entityInQueryIndex, entity);
    31.         if (motionType.Value == BodyMotionType.Kinematic) {
    32.           cmdBuffer.AddComponent<PhysicsVelocity>(entityInQueryIndex, entity, default);
    33.           cmdBuffer.AddComponent<PhysicsGravityFactor>(entityInQueryIndex, entity);
    34.           cmdBuffer.AddComponent<PhysicsMass>(entityInQueryIndex, entity);
    35.           cmdBuffer.RemoveComponent<PhysicsDamping>(entityInQueryIndex, entity);
    36.         }
    37.         if (motionType.Value == BodyMotionType.Dynamic) {
    38.           cmdBuffer.AddComponent<PhysicsVelocity>(entityInQueryIndex, entity);
    39.           cmdBuffer.AddComponent<PhysicsMass>(entityInQueryIndex, entity);
    40.           cmdBuffer.AddComponent<PhysicsDamping>(entityInQueryIndex, entity);
    41.           cmdBuffer.RemoveComponent<PhysicsGravityFactor>(entityInQueryIndex, entity);
    42.         }
    43.       }).ScheduleParallel();
    44.       m_entityCommandBufferSystem.AddJobHandleForProducer(Dependency);
    45.   }
    46. }
     
    Last edited: Apr 29, 2020
  5. Adam-Mechtley

    Adam-Mechtley

    Unity Technologies

    Joined:
    Feb 5, 2007
    Posts:
    290
    In the next update we will have a PhysicsMassOverride (or similar) to easily handle the dynamic/kinematic change. But changing between static and dynamic/kinematic is still going to be best done by adding/remove PhysicsVelocity. A simple component with a toggle value would be nice from a usability perspective, but it actually is detrimental from a performance standpoint because we can no longer associated broadphase trees directly with the results of entity queries. We would have to individually check entities' static/dynamic override value.
     
    KwahuNashoba and steveeHavok like this.