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

[SOLVED] How to do ECS Physics interactions?

Discussion in 'Entity Component System' started by RuanJacobz, Dec 17, 2019.

  1. RuanJacobz

    RuanJacobz

    Joined:
    Jan 24, 2014
    Posts:
    59
    Hey guys, can anyone point me in the right direction or maybe write a small example of how these work?

    Say I have an entity with a health component get hit by an entity with a damage component.
    How can I make an event of this happening?
    And if you're feeling really generous, maybe an example of how to reference these entities?

    I think I have the basic idea down of what do once I have references to the entities at hand;
    but I'm not sure how to get it in the first place.
     
  2. axxessdenied

    axxessdenied

    Joined:
    Nov 29, 2016
    Posts:
    33
    If you pop into my post over here : https://forum.unity.com/threads/sta...s-looking-for-guidance-on-my-approach.794523/ you'll see I have some basic physics going with gravity and collision detection against any entity that has a collider. Should give you an idea of how to get going as there are some helpful responses that helped set me in the right direction and I posted the updated code. Hope that helps. I'm new at this though so I can't guarantee anything :)
     
    RuanJacobz likes this.
  3. Shane_Michael

    Shane_Michael

    Joined:
    Jul 8, 2013
    Posts:
    158
    There is a great talk from Unite 2019 about exactly so I'd highly recommend watching it.

    Briefly, you usually want to use ComponentDataFromEntity when you need to read a value from an entity, and an EntityCommandBuffer when you want to write. The talk goes into more details about when and why you would want to use one over the other.

    Physics Samples on github scene 2d1 uses triggers so you can open that up and experiment with some working code.
     
    RuanJacobz and axxessdenied like this.
  4. RuanJacobz

    RuanJacobz

    Joined:
    Jan 24, 2014
    Posts:
    59
    Hey guys, I finally got this to work after digging through some of the unity physics samples.
    This feels extremely convoluted, though, and I'm a little shocked that I have to write this much code for every trigger/collision event in the future.

    Hopefully this gets simplified down the line.
    I created two simple components: Health and Bullet
    Health has a float 'Value' and bullet has a float 'Damage'
    That's it.

    If anyone is curious what the system looks like to apply the damage:
    Code (CSharp):
    1. using Unity.Burst;
    2. using Unity.Collections;
    3. using Unity.Entities;
    4. using Unity.Jobs;
    5. using Unity.Physics;
    6. using Unity.Physics.Systems;
    7.  
    8. [UpdateAfter(typeof(EndFramePhysicsSystem))]
    9. public class HealthDamageSystem : JobComponentSystem
    10. {
    11.     private BuildPhysicsWorld _buildPhysicsWorldSystem;
    12.     private StepPhysicsWorld _stepPhysicsWorldSystem;
    13.  
    14.     protected override void OnCreate()
    15.     {
    16.         _buildPhysicsWorldSystem = World.GetOrCreateSystem<BuildPhysicsWorld>();
    17.         _stepPhysicsWorldSystem = World.GetOrCreateSystem<StepPhysicsWorld>();
    18.     }
    19.  
    20.     protected override JobHandle OnUpdate(JobHandle inputDeps)
    21.     {
    22.         var jobHandle = new TriggerEventJob()
    23.         {
    24.             HealthGroup = GetComponentDataFromEntity<Health>(),
    25.             BulletGroup = GetComponentDataFromEntity<Bullet>(true),
    26.         }.Schedule(_stepPhysicsWorldSystem.Simulation,
    27.             ref _buildPhysicsWorldSystem.PhysicsWorld, inputDeps);
    28.  
    29.         return jobHandle;
    30.     }
    31.  
    32.     [BurstCompile]
    33.     private struct TriggerEventJob : ITriggerEventsJob
    34.     {
    35.         [ReadOnly] public ComponentDataFromEntity<Bullet> BulletGroup;
    36.         public ComponentDataFromEntity<Health> HealthGroup;
    37.  
    38.         public void Execute(TriggerEvent triggerEvent)
    39.         {
    40.             var entityA = triggerEvent.Entities.EntityA;
    41.             var entityB = triggerEvent.Entities.EntityB;
    42.  
    43.             var bodyAIsBullet = BulletGroup.Exists(entityA);
    44.             var bodyBIsBullet = BulletGroup.Exists(entityB);
    45.  
    46.             var bodyAHasHealth = HealthGroup.Exists(entityA);
    47.             var bodyBHasHealth = HealthGroup.Exists(entityB);
    48.  
    49.             if (bodyAHasHealth && bodyBIsBullet)
    50.             {
    51.                 var bulletComponent = BulletGroup[entityB];
    52.                 var healthComponent = HealthGroup[entityA];
    53.                 healthComponent.Value -= bulletComponent.Damage;
    54.                 HealthGroup[entityA] = healthComponent;
    55.             }
    56.  
    57.             if (!bodyBHasHealth || !bodyAIsBullet) return;
    58.             {
    59.                 var bulletComponent = BulletGroup[entityA];
    60.                 var healthComponent = HealthGroup[entityB];
    61.                 healthComponent.Value -= bulletComponent.Damage;
    62.                 HealthGroup[entityB] = healthComponent;
    63.             }
    64.         }
    65.     }
    66. }
     
    Last edited: Dec 21, 2019
    Hypnotoad0 and Dr_SuiuS like this.