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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

Updating variables inside Update()

Discussion in 'Scripting' started by Batka, May 31, 2019.

  1. Batka

    Batka

    Joined:
    May 23, 2016
    Posts:
    22
    Hello,

    For all my years working with unity, I believed it's bad practice to update variables inside Update() because Update() is called every frame.

    But recently I downloaded complete project from the Asset Store that's created by Unity Technologies, and I while studying it, I noticed this piece of code in the ShopUI.cs script:

    Code (CSharp):
    1.     void Update ()
    2.     {
    3.         coinCounter.text = PlayerData.instance.coins.ToString();
    4.         premiumCounter.text = PlayerData.instance.premium.ToString();
    5.     }
    which means both Text UI objects have their text variable set in the Update() method.

    Now I am wondering if this is good for performance? And if it's good for perfmorance, is it scalable? Like, can I have 6-10 Text objects updated like this?

    Thank you for your time,
     
  2. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,556
    You are quoting something that unfortunately was said carelessly and warrants examination of the context.

    "it's bad practice to update variables inside Update() because Update() is called every frame."

    This, by itself isn't true. There are many, many cases (for example if you use Update() to move or track an object, where updating variables during Update is very good practice.

    Above quote was said in conjunction with expensive (in terms of performance) operations: do not invoke or execute expensive operations during Update, and if you must do that, minimize it. For example calls to GetComponent<>(). GetComponent is an expensive operation that - since it usually returns the same result on most subsequent calls - you can optimize by caching it's result, and then access the cached value much, much faster in Update().

    Now, updating the text for a canvas element is expensive, because it incurs an expensive draw call due to the change in value. That is why you should only update a canvas element whenever it actually changed. So yes, the code you cite is definitely not optimized. A much better version would save the last coin- and premium counters, and update the text only if there was a change. But note that this change does happen in Update(), it's just minimized. Changing variables in Update is not bad practice. Willy nilly wasting performance due to inconsiderately executing operations is.

    So to your second question: does it make a difference if I update all text objects if only one changes? Yes. A better way would be to only update those text elements that actually changed. That being said, since you probably already decreased the number of draw calls to the text objects by an order of magnitude via filtering for a change, the performance gain by optimizing individual text changes is marginal, so a single 'dirty' flag for all text objects usually suffices. The best approach would be to group related text objects, and have a dirty flag per group.
     
    Last edited: May 31, 2019
    Batka likes this.
  3. Batka

    Batka

    Joined:
    May 23, 2016
    Posts:
    22
    Thank you @csofranz for correcting my beliefs and answering my question thoroughly.