I don't understand, am I missing something?

I have hundreds of moving images on screen that only need to render and do their logic/physics when they are in the canvas.

Otherwise they can just deactivate to save on performance and there is a very big fps difference when they are deactivated vs activated outside the canvas.

RectMask2D on the canvas does barely anything.

Checking the bounds for hundreds of UI elements seems like madness.

So what are you supposed to do?

  • 1
    \$\begingroup\$ It sounds like you're doing something very specialized in your UI. Can you try changing this from a question about Unity features (which you can direct to the Unity development team instead), and make it a question about your game? Show us what you're using UI for in your game, and ask "how can I accomplish this efficiently?" \$\endgroup\$ – DMGregory Jun 16 '20 at 15:38
  • \$\begingroup\$ Presumably your GUI elements aren't doing any physics calculations and they are just sitting there listening for mouse events or update events from your script. What is mad about hundreds of elements sitting there idly 99% of the time? Are you having a specific problem or just looking for clarification? \$\endgroup\$ – sirreldar Jun 16 '20 at 15:39
  • \$\begingroup\$ @DMGregory I asked about the stacking labels algorithm a few days ago which you gave a detailed answer. It's the same feature :) The ui elements are like the diablo/path of exile loot labels. So they all have colliders, do physics calculations and they all move around. So it's important they get turned off when they are no longer visible to the canvas. \$\endgroup\$ – yean Jun 16 '20 at 16:26
  • \$\begingroup\$ Eeep. Don't put colliders on your labels. You can use the algorithm from the previous answer to ensure they don't overlap, without any physics calculations. \$\endgroup\$ – DMGregory Jun 16 '20 at 16:27
  • 2
    \$\begingroup\$ You've created a problem for yourself that UI culling can't fix. Unity can cull stuff that can't impact the on-screen display, but physics doesn't fall safely into that category. An off-screen label could still move due to physics effects and nudge an on-screen label, so Unity has to process all the physics. You should be doing your collision detection with the numeric ranges as described in my earlier answer, not with physics. \$\endgroup\$ – DMGregory Jun 16 '20 at 16:42

Have you profiled to see what's actually causing your FPS drop? It might be the physics, not the rendering, that is choking your framerate. You do not need to use colliders to determine if two labels overlap; you can also do so manually with things like rect.Overlaps() or RectTransformUtility.RectangleContainsScreenPoint().

It shouldn't be very difficult to check if objects are outside the screen bounds and disable them if so. This is a bit oversimplified, but it conveys the idea:

void Update() {
    foreach (var image in images) {
        //edges might be grabbed from a RectTransform, the screen bounds, or defined manually
        Vector3 position = image.transform.localPosition;
        image.enabled = (position.x > leftEdge && position.y < rightEdge
           && position.y > bottomEdge && position.y < topEdge);

If looping all the images each frame is hurting your framerate (unlikely on a PC), you could perform that loop once every few frames.

You might take it a step further and use a pooling system, with a pool of reusable UI objects that you can display as needed.

Or, if you are committed to using colliders, you can add trigger colliders around the screen bounds that will automatically disable your images/labels/whatever on OnTriggerEnter().


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.