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
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

limitting the number of collisions a collider per fixedUpdate in Physing2D

Discussion in 'Scripting' started by odoluca, Oct 3, 2019.

  1. odoluca

    odoluca

    Joined:
    Nov 5, 2014
    Posts:
    28
    TLDR: Is there a way to limit number of collisions a rigidbody/collider can enter per fixedUpdate?

    I am building a 2D simulator where thousands of rigidbodies continously collide with one another. I do not have to be deterministic but I have to maximize the number of rigidbodies. However FPS drops significantly at about 500 rigidbodies.
    two biggest responsible parties are:
    Physics2D.CompileContactCallbacks 17%
    Physics2D.Step 15%

    Each rigidbody has an OnCollisitonStay2D() method. I found I can minimize the impact of the code inside with a counter as below;

    Code (CSharp):
    1.  
    2. int totalCollisionsThisFrame =0;
    3.  
    4.     private void LateUpdate()
    5.     {
    6.         totalCollisionsThisFrame = 0;
    7.     }
    8.  
    9.     private void OnCollisionStay2D(Collision2D collision)
    10.     {
    11.         if (totalCollisionsThisFrame < 2)
    12.         {
    13.             animal.Collide(collision.collider);
    14.             totalCollisionsThisFrame++;
    15.         } else {
    16.                 //Reserved
    17.         }
    18.     }
    However, since the OnCollisionStay2D is still called, it impacts unncessarily.

    So to remove the rigidbody from collisions after the first 2 collision detection, I tried the following;

    A). changing the layer once the number of total collisions are above 2 and chaning it back in the LateUpdate() so it wont be part of collision calculations...
    This was very inefficient.

    B). Putting the rigidbody to sleep using rigidbody2D.Sleep() once the number of total collisions are above 2 and Wake() in LateUpdate().... also very inefficient.

    C). IgnoreCollision() doesn't help either. It is not just in efficient, because I don't keep the data (for efficiency purposes) there is no way of reverting it back. There is no method to undo all ignoreCollisions with one go.

    D) I considered ECS for improving efficiency however I can not find any tutorial that uses both ECS, colliders and joints. If you know any it would be appreciated.

    Long story short; my question is;

    1. Is there a way to limit number of collisions a rigidbody/collider can enter per fixedUpdate?

    Thanks in advance
     
  2. alexeu

    alexeu

    Joined:
    Jan 24, 2016
    Posts:
    257
    in 3D the duration of a collision is

    1 * Time.fixedDeltaTime OnCollisionEnter(Collision collision)
    n * Time.fixedDeltaTime OnCollisionStay(Collision collision)
     
  3. odoluca

    odoluca

    Joined:
    Nov 5, 2014
    Posts:
    28
    I am sorry. I failed to understand how this could be useful in my case.
     
  4. alexeu

    alexeu

    Joined:
    Jan 24, 2016
    Posts:
    257
    Oh i was suggesting to use collision duration but i think it will give the same result.
    Anyway, with the code above you should have a better behaviour if you set totalCollisionsThisFrame
    to Zero in OnCollisionExit2D() instead of LateUpdate().

    And its normal that OnCollisionStay2D() keep sending messages as you are stuck in the same collision...
    If you want a single execution, so use OnCollisionEnter2D.
     
    odoluca likes this.
  5. odoluca

    odoluca

    Joined:
    Nov 5, 2014
    Posts:
    28
    Wow thanks, Using onCollisionExit2D instead of LateUpdate actually improved Physics2D.CompileContactCallbacks from 16% to 12%. I am not sure about how gameplay is affected but I didnt notice anything as of yet.

    However OnCollisionEnter2D instead of OnCollisionStay2D would not work for me as somethings need to have extended affect as the contact is remained.

    However, the question still remains: I still wonder if Unity Physics Engine has a way of limiting number of collisions (or collision callbacks) of a rigidbody for each fixedUpdate.