I’m sure I’m not the only one wondering what the most performant and cleanest method for handling projectile collisions in ECS is. It’s an interesting topic. Lots of good guys with guns, lots of bad guys with guns, and LOTS of bullets!
For this analysis, we’re assuming the physics shapes are simple spheres, rectangles, or other primitives. We don’t care about hitting specific body parts - just that the bullet hits the primitive.
So far, here are the strategies I’ve encountered:
-
Use Unity Physics triggers - Using ITriggerEventsJob and triggers, check all collisions and look for bullets hitting things. One good thing is that use of triggers means this code only gets executed when objects collide, but I suspect that unity physics has to a lot of extra collision handling under the hood. [(+)only runs whenever things collide, (-)the unity physics system has more work every frame]
Examples:
DOTS-Shmup3D-sample-master - DOTS-Shmup3D-sample/Assets/Scripts/BaseSystem/CollisionManager.cs at master · Unity-Technologies/DOTS-Shmup3D-sample · GitHub
shaefsky - Handling collisions -
Make a system with a brute-force nested loop “for every target” and “for every bullet” and checks to see if they are close enough to a target. This appears computationally heavy, but then again, perhaps the other methods have to loop through the same number of entities anyway and it’s just hidden under the physics raycast/collision systems. Most of the examples I found using this method are from a couple of years ago - before unity.physics existed. [(-)runs every frame, (-)bullet * target iterations, (+)no extra work for unity physics]
Examples:
AngryDots - https://github.com/UnityTechnologies/AngryBots_ECS/blob/master/AngryDOTS/Assets/Scripts/ECS/Systems/CollisionSystem.cs
IntroToECSFinal - Entity Component System for Unity: Getting Started | Kodeco
Unity-Official-ECS-EntityComponentSystemSamples - Unity-Offical-ECS-EntityComponentSystemSamples/TwoStickShooter/Hybrid/Assets/GameCode/DamageSystem.cs at master · lkihk/Unity-Offical-ECS-EntityComponentSystemSamples · GitHub -
Make a system that loops through every bullet and does a forward raycast, while moving the bullet at the same time. I like this method since it kills two birds with one stone (movement and collision), and because raycasting supposedly pretty fast. If a raycast internally needs to check against everything in the scene, then this method would be the same speed as Method 2. It seems like this method is the most popular one at the moment, but maybe that’s because it’s easier (not necessarily faster), or perhaps it’s because the physics package is relatively new. [(-)runs every frame, (?)one raycast per bullet, (+)no extra loop for bullet movement required].
Examples:
DotsOfTheDead - DOTSoftheDead/Assets/_Project/Scripts/Systems/ProjectileHitDetectionSystem.cs at master · illogika-studio/DOTSoftheDead · GitHub
Opeth001 - Collision Detection projectiles -
Visual Effects Graph - There are a couple of guys on Reddit talking about using VFX Graph with baked textures for bullets because apparently VFXG has some sort of physics collider capability that is separate from unity physics. The GPU does most of the work. This method looks fast, but for me personally, I don’t have enough details to reproduce what they’re talking about. I’m sure there are some shader gurus around who could figure it out. [(-)doesn’t work with unity colliders/shapes, (-)not many details on what they did, (+)runs fast even without ECS, (-)probably doesn’t work on older mobile platforms]
Example: grvChA - Reddit - Dive into anything
For completeness, I also found couple of other projects with solutions that don’t really apply:
SpaceShooterECS used some sort of hash table voodoo… I have no idea what the heck is going on in that code.
SurvivalShooterECS just does an instant-hit raycast (no projectiles)
Unfortunately I don’t know enough about the internal workings of the physics package to make a determination about which one is best.
Any insights for performance pros/cons? Methods I missed? Has anyone done any performance testing to compare the methods or know of someone who has tested some of them?