Siddharth
Siddharth

Reputation: 4312

Improve Frame rate on too many UI Images - Unity UI

In my single page, there were so many textures those I require to render before I was just facing problem in just screen opening but this I was able to resolve this suggestion:

OnBecomeVisible for Canvas UI Objects

Here is the actual code that I used for this purpose:

public void OnValueChangeRefreshCards (Vector2 valueChange)
{
    elapsedYDist += valueChange.y;

    if (elapsedYDist > 3f) {
        elapsedYDist = 0f;
        for (int i = 0; i < GameConstants.TOTAL_ROSE_COUNT; i++) {
            Card card = roseList [i].GetComponent<Card> ();

            if (RendererExtensions.IsVisibleFrom (card.MyRectTransform, Camera.main))
                card.roseImage.enabled = true;
            else
                card.roseImage.enabled = false;
        }
    }
}

But now I started too much framerate lose related issue so even scrolling of page become really difficult for me. Please check the attached video for more clearance about the issue, I was facing. NameThatRose - Low Frame Rate

Please give me some suggestions for next improvements.

EDIT: Here are my profiler output.

Upvotes: 0

Views: 1693

Answers (1)

Umair M
Umair M

Reputation: 10740

You can try few things to find out whats causing the low fps.

  1. Use profiler to deep profile to find out which UI call is taking more time. Like what I did here. As Image inherits from UIMaskableGraphics, it calls MaskableGraphics.OnEnable() every frame for every image in your list. This takes up time which you can see here:

  1. I believe your OnValueChanged method is called every frame this would only multiply the enable/disable iterations and its processing time. You can limit the call by some time, processing 4 times a second for example.

    float timeSinceLastUpdate = 0;
    
    void Update()
    {
        timeSinceLastUpdate += Time.deltaTime;
    }
    
    public void OnValueChangeRefreshCards (Vector2 valueChange)
    {
        if(timeSinceLastUpdate < 0.25f)
        {
            return;
        }
        timeSinceLastUpdate = 0;
    
        // do your stuff here...
    }
    
  2. You have 250+ images to process every frame which is a big deal for older Android devices, again as MaskableGraphics.OnEnable() call can be the culprit. You can avoid changing the state if it is required:

    if (RendererExtensions.IsVisibleFrom (card.MyRectTransform, Camera.main))
    {
        if(!card.roseImage.enalbed)
            card.roseImage.enabled = true;
    }
    else
    {
        if(card.roseImage.enalbed)
            card.roseImage.enabled = false;     
    }
    

Furthermore, following are some helpful links to optimize UI in Unity:

UPDATE:

The following blog provides more information about UI rendering:


Hope this helps :)

Upvotes: 2

Related Questions