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

Question Most performant way to handle bullet collisions

Discussion in '2D' started by DacunaZuke, Jun 6, 2022.

  1. DacunaZuke

    DacunaZuke

    Joined:
    Apr 30, 2022
    Posts:
    10
    I'm creating a bullet hell/shoot 'em up and I want at least a thousand bullets on screen, which can cause performance issues, especially on lower-end hardware.

    My main questions are:
    • What is the most performant way to handle collisions when you have so many GameObjects on screen?
    • Does having a Collider2D and Rigidbody2D on every bullet inherently cause a performance loss, even with something like object pooling?
    For context:

    Right now, I'm using a Collider2D that is attached to the player and every enemy to check for collisions every frame with Collider2D.OverlapCollider. My main problem with this is that every bullet needs a Collider2D and Rigidbody2D attached to it. The Collider2D is necessary for obvious reasons. As for the Rigidbody2D, I think it's necessary because from what I've heard, if you move the bullet with transform.Translate, it causes the 2D physics engine to do some extra calculations for the collider. Maybe this was a bug that was fixed recently?

    I'm thinking of maybe sticking maybe a dozen or less raycasts on every bullet, from the original point to the point where it moves, and see if those intersect with another object. To be honest, this doesn't sound that much better, but it would mean I wouldn't need the Collider2D or Rigidbody2D on the bullets.
     
  2. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,184
    If you want to have large numbers of projectiles on screen the best way is to simply not use GameObjects. Unity's particle systems support collisions and can be modified after they've been emitted to change their behavior.

    https://docs.unity3d.com/ScriptReference/ParticleSystem.html

    https://docs.unity3d.com/ScriptReference/ParticleSystem.GetParticles.html
    https://docs.unity3d.com/ScriptReference/ParticleSystem.SetParticles.html

    https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnParticleCollision.html
     
    DacunaZuke likes this.
  3. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    4,191
    And then there is DOTS with Entities … ;)
     
    DacunaZuke likes this.
  4. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,620
    Why not use physics queries? This is the kind of thing they were created for i.e. detecting contacts with stuff in various ways that don't require a physics component to do so. Raycast, circle cast etc.
     
    DragonCoder and DacunaZuke like this.
  5. DacunaZuke

    DacunaZuke

    Joined:
    Apr 30, 2022
    Posts:
    10
    Thanks everyone!

    I was initially avoiding the particle system because I wanted full control over each individual bullet, however, it seems that the ParticleSystem has ways to iterate over each particle, which might be interesting, although maybe slow?

    I get sold on DOTS quite often, and I do think it's pretty neat. I just wish it had the widespread use of "classic" Unity. Plus, I'm always iffy on using tools that are in beta. I'll try it anyways just because I think it's cool.

    Do you mean something like Physics2D.CircleCastAll? Wouldn't that require either the bullets having a BoxCollider or the bullets themselves making the collision checks against the player/enemies?
     
  6. DragonCoder

    DragonCoder

    Joined:
    Jul 3, 2015
    Posts:
    1,492
    No, those cast methods work on their own, only interacting with other colliders that exist in the world. You can cast from anywhere. It's as if you place a virtual collider (just for this frame) at the position you provide in the call, and check what it would collide with. Same principle as with Raycast, except with said shape instead of an infinite line.

    Nevertheless, looking into particles or DOTS is a good idea for your usecase, since thousands BoxCollider casts every physics frame still sound rather on the heavy side and so many SpriteRenderers are a burden too.
    You can also use particles together with this: https://docs.unity3d.com/Manual/particle-system-job-system-integration.html
    That way you can quite nicely iterate through many thousands of particles. I would recommend this over calling GetParticles and SetParticles manually in Update(), because that would be slower. You can unfortunately not affect singular particles without using the SetParticles method to set all.

    What physics behavior do you want to give the bullets?
    Particles can bounce and be affected by gravity without any additional scripts.
     
    Ryiah and DacunaZuke like this.
  7. DacunaZuke

    DacunaZuke

    Joined:
    Apr 30, 2022
    Posts:
    10
    I think I understand, but wouldn't this mean every enemy bullet would CircleCast against the Player, for instance? Assuming there is no BoxCollider on the bullets.

    Actually nothing besides collisions. I'm moving the bullets through Rigidbody2D.MovePosition right now, so it's a little annoying to have so much of a performance hit just for collisions against a few objects. Hopefully this would make working with ParticleSystems even easier.
     
  8. DragonCoder

    DragonCoder

    Joined:
    Jul 3, 2015
    Posts:
    1,492
    Yes, exactly, but in the end that will have to happen in some shape or form, whether you let colliders do it, cast manually, or have the particle system handle it. I mentioned those in order of speed, I think.

    Do they move in a special way? because particles also have velocity, orientation and rotational speed which are all applied automatically every physics frame.
    The main thing they do not have compared to rigid bodies is mass (which allows for inertia) and in collisions they are represented as circles\spheres.
     
  9. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,184
    ECS is in beta but the JobSystem and Burst are both production ready.
     
    DacunaZuke likes this.
  10. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,620
    Here isn't the place to write a tutorial (there are lots online) and there isn't a specific query I'm telling you to use. Use CircleCast or Raycast, it's kind of irrelevant. Often things like bullets/projectiles use a query to see what they're going to hit in a future step by casting a shape/line in-front of them and then responding to that.

    A query like raycast detects colliders, it doesn't require a collider to work itself. Cast a ray from the bullet position to where you're moving it to, filter by enemies or whatever. Use those results.
     
  11. Shedletsky

    Shedletsky

    Joined:
    Apr 21, 2014
    Posts:
    20
    DacunaZuke likes this.