Collider2D, FPS Drop when dragging and collide object to others (many stacking objects)

hi, I’m new to Unity Collider2D,
as shown in the image below

I tried to drag a char (in the blue rect) to the pile of chars on the right (there are 40 chars stacked), and when collide, the FPS drop

each char have 8 BoxCollider2D (head, body, left hand, right hand, left foot, right foot, eye, forehead)

I didn’t use any RigidBody2D, only use BoxCollider2D in each char…
the plan is, i will code the gameplay logic in OnTriggerEnter2D, OnTriggerStay2D, and OnTriggerExit2D when collision happen.
I set IsTrigger = false for all of the other 40 chars BoxCollider2D.
the only BoxCollider2D with IsTrigger = true is the dragged char

For now, I haven’t code OnTriggerEnter2D, OnTriggerStay2D, and OnTriggerExit2 at all.
I simply code and make that 1 char to follow mouse drag position, drag it to the 40 chars, and the FPS is going down.
any clue how to improve the FPS?

You could start by stop using the Transform when manipulating physics. If you’re not using a Rigidbody2D then the collider is Static (non-moving) and cannot be moved. If you modify the Transform those colliders will be completely recreated. If it moves in 2D physics, you move the Rigidbody2D via its API. Note that moving it in the Editor isn’t physical movement either, that just updates the Transform because it’s how you author stuff, not play the actual game. Physics movement in the game is done via the Rigidbody2D.

TBH I’ve never understand why devs avoid adding in a Rigidbody2D because of some notion that it’d somehow make it worse when it’s quite the opposite and causes terrible problems. There’s a body-type on the Rigidbody2D so you can choose what it does. It doesn’t have to be Dynamic.

Overlapping 40 things on top of each other means there are potential 40 x 40 x 8 contacts (potentiall x2 contact points). This is made worse if they are being recreated because of what I said above. The profiler will also show you contact contact too.

If none of these have any Rigidbody2D then you won’t ever get any callbacks of any kind because Static never contact Static because it wouldn’t make sense. They are Static and don’t move! This is what Kinematic is for if you want explicit positional control.

Also, if you look at the profiler, FixedUpdate is being called 4 times because everything is taking too long. This calls animation, scripts and physics. If you’re causing physics to do lots and lots of work then this can be self manifesting.

thanks for the reply

so first of all i need to add rigidbody to all of the characters, and then using rigidbody API to move the dragged char to follow the mouse pointer, am I right?

To address movement of colliders, yes. Colliders are attached (actually created against) a Rigidbody2D. When the Rigidbody2D moves, nothing about the Colliders need to change. If you don’t have a Rigidbody2D you cannot move it. Changing the Transform isn’t moving it; it’s completely recreating it.

There’s many ways to move a Rigidbody2D but if it’s Dynamic and you want mouse-dragging, here’s an example of how you could do that (lots of ways though):
https://www.youtube.com/watch?v=4NSKN3L0fvE

If these are Kinematic Rigidbody2D then you should instead use MovePosition and MoveRotation which are compatible with when you use Rigidbody2D interpolation.

thanks for explaining it very clear to me
I assume modifying the transform, not only position, but rotation and scale, will also recreating the colliders?
so we rotate and scale via rigidbody api also?

2D only has three degrees of freedom all provided by the Rigidbody2D. Those are X position, Y Position and Z rotation.

You’re asking but there’s a scripting doc available here. No scaling options.

If you perform any Transform scaling then the collider will need to be recreated from scratch.

You have to understand what the physics engine wants colliders to not change (be immutable) because it’s expensive to do so. This is why you move a body and colliders are just along for the ride without needing to be changed. Scaling changes their geometry.

thanks, I will give it a try and see the performance

I did a simple test, and the result is still a Low FPS when dragged 1 object to pile of objects (30)
https://www.dropbox.com/s/lnk0xgjb9i0kn5w/Screenshot 2022-11-10 140821.png?dl=0

The code is very straight forward (moving the dragged char via its Rigidbody2D.MovePosition)
https://www.dropbox.com/s/fx3d0ej6v07ecyw/Screenshot 2022-11-10 140530.png?dl=0

Note that the red face char is the only char we can drag.

GameObjects condition =

  • Each char have 8 colliders.
  • The only IsTrigger = true is the dragged char colliders (the red face char).
  • Each char have 1 Rigidbody2D, attached to char main GameObject, with Kinematic type.
  • For the dragged object, I move it via Rigidbody2D.MovePosition in FixedUpdate

Is that FPS considering normal for that amount of objects and colliders? if yes, any idea to make a better (faster) collider check for 2D games, that involved a lot of small objects, characters and colliders?

Re: Collider2D, FPS Drop when dragging and collide object to others (many stacking objects)

Obviously I cannot debug this for you, all I see is a rough description and a 100ms figure but that figure is huge for what you’re describing so look at what I said in the above post regarding all those overlapping objects and potentially a lot of contacts. Note that showing the total time in CPU view provides no extra information really. This is why there’s a Physics2D area in the profiler.

TBH I don’t understand why each of these characters are even set to contact each other; they are completely overlapped. What possible use would having all those contact points provide? Shouldn’t they all simply be triggers? In the end though, without knowing what is causing it, the question is kind of irrelevant I guess.

I would’ve thought you’d be able to identify the root cause though by removing things to find out what is causing it. If each char that overlaps increases it then have you looked at anything beyond the total time taken i.e. look at the Physics 2D profiler area? Your reply would suggest I could somehow know by seeing 100ms value which I cannot. :slight_smile:

thanks for the explanations

I decided to disabled all 2d collider, and only enabled any collideres that can collide with the dragged object.
that way, the FPS still can be stable :slight_smile:

Okay, I don’t understand why they need to be contacting for such gross overlaps. Surely you’d use the layer collision matrix to stop them touching each other.

Anyway if you think you’ve sovled it that’s good.

yes it should not contacting each others (each col to each col) , it’s happen because my misunderstanding re: unity physics (totally new into physics engine), thanks again for your helps, have a good one!

1 Like

Okay cool. So if each of these characters and all their GameObject are on a layer named (say) “Player” then go to the Layer Collision Matrix in the Physics 2D Settings and deselect the row/column for “Player”. They will never then contact other other.