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

Update component data in ICollisionEventsJob

Discussion in 'Physics for ECS' started by stefan-falk, Jan 5, 2020.

  1. stefan-falk

    stefan-falk

    Joined:
    Nov 24, 2019
    Posts:
    15
    Hi!

    I am trying to update components data on colliding entities. In the end I want to be able to apply damage to units but I am not sure how to do this using Unity Physics.

    Currently I am running the following code (which is not working as it does not update the Speed.Value - just for testing purposes)

    Code (CSharp):
    1. using ECS.Components;
    2. using Unity.Burst;
    3. using Unity.Collections;
    4. using Unity.Entities;
    5. using Unity.Jobs;
    6. using Unity.Physics;
    7. using Unity.Physics.Systems;
    8. using UnityEngine;
    9.  
    10.  
    11. // READ https://forum.unity.com/threads/collision-detection-projectiles.735992/
    12.  
    13. namespace ECS.Systems
    14. {
    15.     [UpdateAfter(typeof(EndFramePhysicsSystem))]
    16.     public class CollisionEventSystem : JobComponentSystem
    17.     {
    18.         private BuildPhysicsWorld _physicsWorld;
    19.  
    20.         private StepPhysicsWorld _stepPhysicsWorld;
    21.  
    22.         protected override void OnCreate()
    23.         {
    24.             this._physicsWorld = World.GetOrCreateSystem<BuildPhysicsWorld>();
    25.             this._stepPhysicsWorld = World.GetOrCreateSystem<StepPhysicsWorld>();
    26.         }
    27.  
    28.         protected override JobHandle OnUpdate(JobHandle inputDeps)
    29.         {
    30.             var job = new CollisionEventSystemJob
    31.             {
    32.                 SpeedComponentData = GetComponentDataFromEntity<Speed>()
    33.             };
    34.            
    35.             var jobHandle = job.Schedule(
    36.                 this._stepPhysicsWorld.Simulation,
    37.                 ref this._physicsWorld.PhysicsWorld,
    38.                 inputDeps
    39.             );
    40.             jobHandle.Complete();
    41.             return jobHandle;
    42.         }
    43.     }
    44.  
    45.     [BurstCompile]
    46.     struct CollisionEventSystemJob : ICollisionEventsJob
    47.     {
    48.         public ComponentDataFromEntity<Speed> SpeedComponentData;
    49.         public void Execute(CollisionEvent collisionEvent)
    50.         {
    51.             var entityA = collisionEvent.Entities.EntityA;
    52.             var entityB = collisionEvent.Entities.EntityB;
    53.  
    54.             if (SpeedComponentData.Exists(entityA) && SpeedComponentData.Exists(entityB))
    55.             {
    56.                 Debug.Log("Setting Speed.");
    57.                 Speed speed = SpeedComponentData[entityA];
    58.                 speed.Value *= 2;
    59.             }
    60.         }
    61.     }
    62. }
    However, I am not so sure if this makes sense, even if it worked. After all, I might have to destroy the projectile-entity and subtract the damage from the Health.Value of the hit entity. Not sure if this is the right place to take care of this.

    Anyway, I can't find a proper solution to this. Can I update values inside the CollisionEventSystemJob or do I have to collect data and finish the job elsewhere?

    Sorry if this is a silly question, I am pretty new to Unity and, obviously, also to DOTS.
     
  2. Adam-Mechtley

    Adam-Mechtley

    Administrator

    Joined:
    Feb 5, 2007
    Posts:
    290
    I would recommend something like a Damage component or DynamicBuffer. So basically if something can receive damage, you just accumulate or append to that value/buffer in your collision event job, and then have a separate, dependent job that applies the results of that Damage to a Health component. Basically, you have no guarantees about the order any of your contact events are processed on a given frame, so you don't necessarily want to modify or destroy something in the contact event job itself, if the modified value might affect another contact event on that same frame.
     
    edalbeci and steveeHavok like this.
  3. edalbeci

    edalbeci

    Joined:
    Jan 21, 2018
    Posts:
    36
  4. crocvr

    crocvr

    Joined:
    Oct 7, 2015
    Posts:
    44
    Can you show a sample with buffering? I mean, i am not sure how to return something from a job without applying modifications to components of some entity.