Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by gustavoarcanjo · Feb 01, 2017 at 09:04 AM · unity 5uicanvasoptimizationrenderer.enabled

Disabling canvas renderer optimization

Unity's UI optimization tutorial mentions that one way to optimize hiding parts of the UI would be by Disabling Canvas Renderers.

However, they don't exactly say how this should be done, and I haven't found that on the current documentation for Canvas Renderers or the legacy one (since this tutorial was checked with Unity 5.3).

The only thing they say is that what should be done is to

[...] place the UI to be shown/hidden onto its own Canvas or Sub-canvas and then to merely enable/disable the Canvas Renderer component attached to that Canvas or Sub-canvas.

Is there a way to actually enable/disable the Canvas Renderer component or is there another optimized way to stop rendering UI Graphic components from a Sub-canvas without discarding VBO data?

I know that I can hide the UI objects by disabling the Canvas, disabling the GameObject or setting the Canvas Group alpha to 0, but I really need to make a WebGL build as optimized as possible, since the client needs it to run on an iPad, so please help me if you can.

Thanks.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

4 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by Scoutas · Feb 07, 2017 at 02:03 AM

It's as simple as disabling the Canvas component, as it's the thing that's handling all the rendering of the UI.

Did a test with thousands of Canvas objects, and it did increase the render time by around 1ms for me, and disabling the Canvas component removed that delay.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image gustavoarcanjo · Feb 07, 2017 at 05:07 PM 0
Share

Hi Scoutas, thank you for your answer.

I'm not sure if that is the case, but can you tell me if there were any lag spikes when disabling or reenabling the Canvas objects?

The reason why I'm in doubt is because the documentation states that, when disabling a Canvas Renderer component attached to the Canvas or Sub-Canvas:

[...] this will not eli$$anonymous$$ate the UI’s Graphics from the GraphicRegistry and so they will still be present in the list of components to check for a Graphic Raycast. It does not disable any $$anonymous$$onoBehaviours within the hidden UI, and so these $$anonymous$$onoBehaviours will still receive Unity lifecycle callbacks, such as Update.

I believe that this doesn't happen when the Canvas component is disabled, since the Event System stop logging information about raycasting of those components under the disabled Canvas.

As a comparison, recently, by exa$$anonymous$$ing the Toggle source code, I've noticed that what they do to stop rendering the target graphic when the toggle is off is by using graphic.canvasRenderer.SetAlpha(0f);

Even though this actually disables the rendering and keeps the graphic in the GraphicRegistry since raycast still apply to the invisible object, it doesn't affect the rendering of the graphic's children. If it did, it would be just as the documentation says things should behave and it would be the answer to my problems.

By disabling the canvas component, on the other hand, the rendering of all the elements inside said canvas actually stop, but I believe it also eli$$anonymous$$ates those graphics from the GraphicRegistry, since the now invisible buttons are not clickable anymore.

So either:

  1. There might be an overhead when enabling/disabling the Canvas component that should not be present when disabling the canvas renderer of attached to a Canvas (even though I'm not quite sure how that should be done)

  2. That is how things should be done and the Event System checks the raycast for the UI's Graphics under the disabled Canvas, but doesn't say that those Graphics were checked. But I'm inclined to say that is not the case, since the Toggle behaves differently.

Thank you for your help.

avatar image Scoutas · Feb 07, 2017 at 06:31 PM 1
Share

Okay, I did a tiny ammount of digging around. I'm not exactly sure how it all worked before, but right now, each UI element has it's own CanvasRenderer component inside of them (e.g. an Image has it's own CanvasRenderer and it's dependant on the Image component, so it can't be removed).

Anyway, did some tests. The rendering is actually not the most demanding thing from this whole thing. Did a test again, using lots and lots of canvases and buttons. The rendering for that only really took around 0.5ms at most. Setting the alpha of the renderers actually removed that 0.5ms delay, and I could still use the buttons that were in the UI.

On the other hand, the EventSystem is rather demanding. With around 800 buttons altogether, one click jumped the delay from ~0.8ms, to 5-6ms.

Anyway, the take-away is this: There's no actual way to disable the CanvasRenderer. If you disable the UIComponent of it, you lose the raycasting target and can't actually interact with any of them.

Of course, I tested this all out with built-in Unity UI buttons, so I would guess that more complex imagery and such would be a little more demanding, but setting the alpha of these components to 0, actually reduces the rendering load. You would have to play around with some setting of it afterwards, so that it wouldn't turn back on when you don't want to and such.

As for disabling the children alphas - I used a code that would get every single CanvasRenderer component from the Canvas children and set all their alphas to 0.

 public class Alpha : $$anonymous$$onoBehaviour{
     public GameObject canvas;
 
     void Start(){
         CanvasRenderer[] canvasRenderers = canvas.GetComponentsInChildren<CanvasRenderer>();
     foreach(CanvasRenderer c in canvasRenderers){
         c.SetAlpha(0);
     }
 }
 }

It's not that demanding, and it does the job.

I'm sorry if I am misunderstanding your question, because it feels a little bit like I am, but I hope you'll get something out of this all.

avatar image gustavoarcanjo Scoutas · Feb 07, 2017 at 06:57 PM 0
Share

Yeah, I guess the best option would be to set the alpha of the canvas renderer of each child object inside a canvas, like you did, whenever I need to disable/enable objects.

$$anonymous$$y problem was more with the lack of clear information on Unity's UI optimization tutorial than everything, but I guess this solution is the closest thing to how the tutorial said it should behave.

Thanks

avatar image
0

Answer by sddayord · Feb 07, 2017 at 05:38 PM

Hi,

not 100% sure on this but try:

 Canvas c;
 c.GetComponent<CanvasRenderer>().cull = false;

The problem with this is that this doesn't seem to propagate to the children so you may need to individually reference their canvas components although I don't know if this will be faster. It may be a Unity issue at this point you never know. I tried it on 5.2

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by Bertlapp · Mar 28, 2019 at 09:04 PM

Nice,

This did the trick for my dynamic scroll list filled with score views and Facebook picture.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by PuzzledBoy · May 06, 2019 at 08:38 AM

I don't think exist a way to disable "Canvas Renderer".

you can log the dirty state change by call "RegisterDirtyLayoutCallBack" or "RegisterDirtyVerticesCallBack" on Awake

and you can find out that "CanvasRenderer.cull = false" or "CanvasRenderer.SetAlpha(0)"
still cause a dirty.

The UI optimization tutorial said that

"One possible, but hacky, workaround is to place the UI to be shown/hidden onto its own Canvas or Sub-canvas and then to merely enable/disable the Canvas component on this object."

So the poper way to do that is create a Canvas Component and disable it.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

9 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Unity UI Position 2 Answers

UI doesn't render after scene reload. 0 Answers

Problem with build version 1 Answer

Play MP4 on UI? (Unity 3D 2018.2) 0 Answers

2d image does not scale/stretch correctly 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges