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. Dismiss Notice

Unity UI Why do Graphic components register with the GraphicRegistry even if they aren't raycastTargets?

Discussion in 'UGUI & TextMesh Pro' started by CanisLupus, Dec 13, 2017.

  1. CanisLupus

    CanisLupus

    Joined:
    Jul 29, 2013
    Posts:
    427
    We were optimizing UI/events performance for battery savings in our application. After creating our own CustomGraphicsRaycaster and removing functionality we didn't need, we noticed that what was now taking up most of the time was iterating through all Graphics given by GraphicRegistry.GetGraphicsForCanvas(canvas), in the raycaster:

    Code (CSharp):
    1.    int totalCount = foundGraphics.Count;
    2.    for (int i = 0; i < totalCount; ++i)
    3.    {
    4.        Graphic graphic = foundGraphics[i];
    5.        // ...
    Essentially, the main performance hit is now using the indexer for foundGraphics, which is an IndexedSet. We also see that right afterwards, this happens:

    Code (CSharp):
    1.    if (graphic.depth == -1 || !graphic.raycastTarget || graphic.canvasRenderer.cull)
    2.        continue;
    So if the graphic is not a raycastTarget or the depth is -1, we shouldn't do anything with it. After checking briefly with your UI repository at https://bitbucket.org/Unity-Technologies/ui, we found that the GraphicRaycaster is the only class using GraphicRegistry.GetGraphicsForCanvas(), and the Graphics themselves are the only ones registering with it using RegisterGraphicForCanvas.

    Our question is, therefore, why do Graphics that are not raycastTargets register themselves with the GraphicRegistry? This is not easy to solve on our side, since trying to unregister non-raycastTarget graphics manually still fights with them re-registering themselves on OnEnable, for example. We understand that more things could be done with the GraphicRegistry involving ALL graphics, but it is not the case, and the Raycast loop is unnecessarily including every Graphic, even if it is irrelevant for events.

    Additionally, if it is not in your plans to change this, we wanted to suggest checking graphic.depth last in the above "if" statement. The depth getter returns canvasRenderer.absoluteDepth, which is in a black box (CanvasRenderer) and doing who-knows-what. ;) It seems considerably more expensive than the other two checks in our experience.

    Cheers!
    Daniel Lobo
     
    Ultroman likes this.
  2. CanisLupus

    CanisLupus

    Joined:
    Jul 29, 2013
    Posts:
    427
    I was hoping that someone from the Unity UI team could comment this. I'd mention a specific person if I knew who.
     
  3. Sprawl

    Sprawl

    Joined:
    Jan 19, 2014
    Posts:
    42
    @CanisLupus I know it's an old post now, but did you ever find a answer to this?
     
  4. CanisLupus

    CanisLupus

    Joined:
    Jul 29, 2013
    Posts:
    427
    Hey @Sprawl, sadly no. At the time we just implemented our own GraphicRaycaster (CustomGraphicRaycaster) and started using it in all our projects for essentially free battery (checking graphic.depth last, removing code useless to us, and stopping the raycast at the top intersection instead of building a list of all intersections). The question about the Graphics registration remains unanswered.