Search Unity

Collision Point

Discussion in 'DOTS Physics' started by iiziziz, Mar 22, 2020.

  1. iiziziz

    iiziziz

    Joined:
    Mar 20, 2014
    Posts:
    11
    Hi there,

    I'm relatively new with DOTS and playing for the first time with
    ICollisionEventJob
    .

    By now everything was going well, triggering the event and my job doing some stuff.
    But my logic has to be applied only if my player entity hits the ground below the player.

    Previously, to do this, I was comparing top and bottom of each box colliders but I was looking for a different way to do this with
    CollisionEvent
    .

    Is there a way to find the collision point related to the
    CollisionEvent
    ?
     
  2. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    Hello, have you tried to call CalculateDetails() on your CollisionEvent? It will give you Details that provide EstimatedContactPointPositions and EstimatedImpulse.
     
  3. iiziziz

    iiziziz

    Joined:
    Mar 20, 2014
    Posts:
    11
    I tried to swap to an
    IContactsJob
    but constantly having issues with
    NumWorkItems
    being deallocated.

    I'm getting this message :

    Code (CSharp):
    1. InvalidOperationException: The NativeContainer MySystemJob.NumWorkItems has been deallocated. All containers must be valid when scheduling a job.
    2. Unity.Jobs.LowLevel.Unsafe.JobsUtility.Schedule (Unity.Jobs.LowLevel.Unsafe.JobsUtility+JobScheduleParameters& parameters) (at <58a34b0a618d424bb5fc18bb9bcdac20>:0)
    3. Unity.Physics.IContactsJobExtensions.ScheduleUnityPhysicsContactsJob[T] (T jobData, Unity.Physics.ISimulation simulation, Unity.Physics.PhysicsWorld& world, Unity.Jobs.JobHandle inputDeps) (at Library/PackageCache/com.unity.physics@0.3.0-preview.1/Unity.Physics/Dynamics/Simulation/IContactsJob.cs:160)
    4. Unity.Physics.IContactsJobExtensions.Schedule[T] (T jobData, Unity.Physics.ISimulation simulation, Unity.Physics.PhysicsWorld& world, Unity.Jobs.JobHandle inputDeps) (at Library/PackageCache/com.unity.physics@0.3.0-preview.1/Unity.Physics/Dynamics/Simulation/IContactsJob.cs:122)
    5. Assets.Scripts._ECS.MySystems.MySystem.OnUpdate (Unity.Jobs.JobHandle inputDeps) (at Assets/Scripts/_ECS/MySystems/MySystem.cs:161)
    6. Unity.Entities.JobComponentSystem.Update () (at Library/PackageCache/com.unity.entities@0.8.0-preview.8/Unity.Entities/JobComponentSystem.cs:129)
    7. Unity.Entities.ComponentSystemGroup.UpdateAllSystems () (at Library/PackageCache/com.unity.entities@0.8.0-preview.8/Unity.Entities/ComponentSystemGroup.cs:134)
    8. UnityEngine.Debug:LogException(Exception)
    9. Unity.Debug:LogException(Exception) (at Library/PackageCache/com.unity.entities@0.8.0-preview.8/Unity.Entities/Stubs/Unity/Debug.cs:19)
    10. Unity.Entities.ComponentSystemGroup:UpdateAllSystems() (at Library/PackageCache/com.unity.entities@0.8.0-preview.8/Unity.Entities/ComponentSystemGroup.cs:138)
    11. Unity.Entities.ComponentSystemGroup:OnUpdate() (at Library/PackageCache/com.unity.entities@0.8.0-preview.8/Unity.Entities/ComponentSystemGroup.cs:114)
    12. Unity.Entities.ComponentSystem:Update() (at Library/PackageCache/com.unity.entities@0.8.0-preview.8/Unity.Entities/ComponentSystem.cs:108)
    13. Unity.Entities.DummyDelegateWrapper:TriggerUpdate() (at Library/PackageCache/com.unity.entities@0.8.0-preview.8/Unity.Entities/ScriptBehaviourUpdateOrder.cs:152)
    Is this a bug/known issue or am I doing something wrong with this type of job ?
     
  4. iiziziz

    iiziziz

    Joined:
    Mar 20, 2014
    Posts:
    11
    Thanks ! It seems to be what I was looking for.
     
  5. BigRookGames

    BigRookGames

    Joined:
    Nov 24, 2014
    Posts:
    305
    Is it possible to make this call in the ICollisionEventsJob? When called I get an error stating that " To guarantee safety, you must include ExportPhysicsWorld:Export"

    Code (CSharp):
    1.  [UpdateAfter(typeof(StepPhysicsWorld)), UpdateBefore(typeof(EndFramePhysicsSystem))]
    2.     struct CollisionEventImpulseJob : ICollisionEventsJob
    3.     {
    4.         [ReadOnly] public ComponentDataFromEntity<CollisionEventImpulse> ColliderEventImpulseGroup;
    5.         public EntityCommandBuffer.ParallelWriter cBuffer;
    6.         public PhysicsWorld physicsWorld;
    7.         //public ComponentDataFromEntity<PhysicsVelocity> PhysicsVelocityGroup;
    8.  
    9.         [DeallocateOnJobCompletion]
    10.         public NativeArray<Entity> removeEntities;
    11.  
    12.         public void Execute(CollisionEvent collisionEvent)
    13.         {
    14.  
    15.             CollisionEvent.Details collisionDetails = collisionEvent.CalculateDetails(ref physicsWorld);
     
  6. BigRookGames

    BigRookGames

    Joined:
    Nov 24, 2014
    Posts:
    305
    When running after ExportPhysicsWorld it seems to run, but the contact point of the projectile is sometimes inside of the mesh of the item being hit.

    I guess it is probably best to get the surface location on the object being hit instead of using the AverageContactPointPosition to determine where the collision effect should be spawned.

    Is there a better way to determine the surface contact point of the initial collision?
     
  7. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    You have the EstimatedContactPointPositions in the CollisionEvent.Details list. You can then examine the contact points, you should be seeing 1 for vertex collision, 2 for edge, and 3 or more for face collision.

    I still can't understand the initial problem here, the snippet seems a bit cut off, so I don't know what you are doing with the collision details.
     
    BigRookGames likes this.
  8. BigRookGames

    BigRookGames

    Joined:
    Nov 24, 2014
    Posts:
    305
    I am spawning a particle system at the point of the collision.
    Where do I see the contact point information? Is that in the collisionDetails? I seem to be getting 2 values in the array. the first value always seems to be the one closer to the surface of the object that was hit:
    upload_2020-10-19_12-32-14.png
    So I am using the first one as the world position to spawn the impact effect, but more often than not it is spawning inside of the wall and it cannot be seen:

    so they are spawning just inside of the other object.

    Inside of the collision event I am adding a collisiontag to the bullet component which holds information fo the contact point:
    Code (CSharp):
    1. cBuffer.AddComponent<BulletCollisionTag>(0, entityBullet,
    2.                 new BulletCollisionTag
    3.                 {
    4.                     targetEntity = isBodyARepulser ? entityB : entityA,
    5.                     contactPointEstimate = collisionDetails.EstimatedContactPointPositions[0]// AverageContactPointPosition
    6.                 }) ;
    It would be pretty easy to do a raycast from the position the entity was a frame before the collision to determine the exact surface location but I was assuming this information might already be calculated by the physics engine.


    EDIT____
    Also I noticed when turning on the debugger that the collider (I assume that the green line is the collider) is behind the mesh:
    upload_2020-10-19_13-49-21.png
     
    Last edited: Oct 19, 2020
  9. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    These contact points are estimated, not 100% correct, because the solver is predictive and never calculates the exact point of contact. If you have large rotations of the body, they would be more wrong. Also if they are really fast. In your case you probably need to do some smart logic to determine a better hit position, although I would expect that this scenario should be ok. What's the collider of the bullets?

    Green lines are the edges of the collider, so that's where physics will stop the object. If that is inside the graphical representation, you won't be able to see the sparks.
     
  10. BigRookGames

    BigRookGames

    Joined:
    Nov 24, 2014
    Posts:
    305
    Okay, I can increase the accuracy of the impact point by shooting a raycast from the spot that would have been one position prior to the collision. I suppose finding the closest point to the collider from that location would also work.

    Given that for my application there can potentially be a very large amount of projectiles, is one much more performant over the other?

    And regarding the green lines from the picture above, the projectiles' mesh seems to be in front of the green line of its own collider. The projectiles are moving pretty fast, but I would assume I am doing something wrong since they are not in sync with each other. It could also be adding to the offset of the impact point issue. What might be causing this offset? i circled the collider (c) and the bullet mesh (b) in the picture: upload_2020-10-20_4-50-17.png
     
  11. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    It could be the ordering of when you update position. Graphics should hear about position from physics, not do it on its own. Also, your collider might be offset locally. Look at frame 1. If they are offset, it could be that it's just moved. If they are in the same position in frame 1, it's probably the update order. When you fix this, you won't need the raycast. :)
     
  12. BigRookGames

    BigRookGames

    Joined:
    Nov 24, 2014
    Posts:
    305
    @petarmHavok What would be the best time to update? It is being updated in a standard SystemBase using a .Run() execution. I tried updating before physics but still getting the same issue.

    Also, if it makes a difference, I am spawning them from a prefab entity (generated at awake and stored with the Prefab component, causing it to be disabled)
     
  13. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    Ideally you would read it from ECS data, after the ExportPhysicsWorld and render it. ExportPhysicsWorld writes new physics position to ECS, and after that the position is the same as in physics. Not sure if you were doing it this way.

    Also make sure to check initially whether you have some offset between graphics and physics representations.
     
  14. BigRookGames

    BigRookGames

    Joined:
    Nov 24, 2014
    Posts:
    305
    Thanks, @petarmHavok, I will go through the order of operations again and see what is causing the issue. I don't believe it is an offset. I decreased the manual movement over time and the collider is correctly positioned when the manual movement reaches zero, so it does seem to be due to when it is updated.
     
    petarmHavok likes this.
  15. BigRookGames

    BigRookGames

    Joined:
    Nov 24, 2014
    Posts:
    305
    @petarmHavok, So I was able to fix the collider being offset, but still having problems with the correct location of the impact point.

    I did notice that the debugger has the information for the exact point, the pink 3d cross emblems appear exactly on the surface, while the impact vfx spawn behind it (using collisionEvent.CalculateDetails(ref physicsWorld))

    What variable or data is the debugger pulling the point for the emblem placements?

    in the video you see the bullet travel through the wall and the debug emblems placed correctly on the surface of the object:



    And yes, I checked the offset of the vfx to make sure it is positioned correctly :)
     

    Attached Files:

  16. BigRookGames

    BigRookGames

    Joined:
    Nov 24, 2014
    Posts:
    305
    Okay, so the collision point calculated was correct it seems, and it was my mistake as the point being used was the transform of the entity, instead of the saved data point. Looks good now! Thank you for your help.
     
  17. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    Glad it worked!
     
    BigRookGames likes this.
unityunity