Assignments to Text.text

Firstly, I’m not sure I’m posting in this in the right sub-forum, I’m kind of confused by the different UIs available here. I’m running Unity 2020.3.30f1 and talking about the objects created by adding UI->Text in the interface.

I want to have a UI element that writes out the value of some variable that, for convenience, I’m storing in a static class. The code looks something like

    class MyTextClass : MonoBehaviour
    {
        public Text DisplayText;

        void Start() => DisplayText.text = "";

        void Update()
        {
            DisplayText.text = $"Value is {MyStaticClass.Value}";
        }
    }

I was wondering however if this is inefficient because I’m forcing it to be re-rendered every frame? I’m guessing that assigning to Text.text might call something behind the scene that makes the engine render, but I really have no idea how it actually works and haven’t found anything in the docs. All that to ask, is it considerably more efficient to cache things I don’t assign to Text.text as much, like this? Obviously one single small block of text isn’t going to kill performance, but I’ll have many elements like this and I’d like to get into good habits early on.

    class MyTextClass : MonoBehaviour
    {
        public Text DisplayText;
        private int CacheValue;

        void Start() => DisplayText.text = "";

        void Update()
        {
            if (CacheValue != MyStaticClass.Value)
            {
                CacheValue = MyStaticClass.Value;
                DisplayText.text = $"Value is {CacheValue}";
            }
        }
    }

Or am I doing this all wrong and I should be “pushing” the MyStaticClass.Value to the UI every time it changes? If so, some pointers to an example on how to do it would be great.

On a minor, related, note: my IDE (VisualStudio 2022) complains with Warning S1104 that DisplayText is a field and tells me to encapsulate it as a property. When I do that, however, the script is no longer recognised by Unity as having text to display. Is there a way out a this?

Nothing? Is this a pointless question to ask, in the wrong section, or am I missing something here?

You are correct - don’t do:

void Update()
{
     DisplayText.text = $"Value is {MyStaticClass.Value}";
}

Every frame like that. I’m not sure if the text itself has an internal isDirty check for whether the text actually changed to avoid a rebuild, but I’m pretty sure it doesn’t. Also it is certainly good practice to not use string interpolation every frame because that creates garbage.

Your workaround, caching the last value locally, is a common way to avoid dirtying.

In general it’s best to not update the UI unless you actually have a change. The major counterpoint to that is that it may be best to do an optimization pass later to prototype as fast as possible.

See 23:30 in the below video for a sense for the performance characteristics of the UI.

1 Like

Try making the field private and using the SerializeField attribute. Unity will still allow you to interact with this field in the Inspector.

[SerializeField] private Text displayText;

But if that’s annoying you can ignore it.

Note: I’ve also changed DisplayText to displayText because that’s standard C# practice for fields. Capitalizing the first letter is convention for Properties. See MSDN on properties for more.

Awesome, thanks, I’m glad that my intuition was mostly right here. Is there a way to see what the underlying unity code actually does so I can check if Text has an internal isDirty check itself? That would generally be helpful in the future for other similar questions.

Before I worked at Unity, I used extensively the ILSpy extension for Visual Studio. It works well, but the official statement would probably to find the relevant code in the Unity c# reference or directly in the package code.

I moved the thread to UGUI because you are using that UI system. We really don’t mind changing the thread location, so you did the good thing in posting in the wrong one when you don’t know), but I am working on UI Toolkit. So I will not monitor this thread :ping me directly if you need more details regarding the C# reference!

Have a good day!

1 Like