Search Unity

How to write text on screen programmatically in newer version of Unity (not using GUI.Label)?

Discussion in 'Getting Started' started by Valynna, Apr 22, 2021.

  1. Valynna

    Valynna

    Joined:
    Apr 1, 2021
    Posts:
    39
    Reading up on the internet, it seems like GUI.Label is out and UnityEngine.UI -- text is in.

    So I'm trying to get this done, but can't seem to figure it out. This is the current function that I call in my Awake() function.

    Code (CSharp):
    1.     void awake_UIfps()
    2.     {
    3.         UI_fps = new GameObject("UI FPS");
    4.         UI_fps.AddComponent<Text>();
    5.         UI_fps.transform.parent = this.transform;
    6.         UI_fps.layer = 5;
    7.  
    8.         Font ArialFont = (Font)Resources.GetBuiltinResource(typeof(Font), "Arial.ttf");
    9.         UI_fps.GetComponent<Text>().font = ArialFont;
    10.         UI_fps.GetComponent<Text>().material = ArialFont.material;
    11.     }
    and later in my start, I call the following function.

    Code (CSharp):
    1.    private void init_UI_fps()
    2.     {
    3.         UI_fps.GetComponent<Text>().text = "FPS Text INIT";
    4.     }
    I mean yeah, sure. I know I need to set the rect transform limits and what not to fit the screen, but I can't get anything to show up at all. what gives? Am I missing some essential command?
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Well the standard way is not to create your UI component at runtime. Yes, it's possible, if you really know what you're doing, but you don't yet, so stick to the standard way.

    The standard way is to create and configure your UI (which needs to be inside a Canvas — probably the key bit you're missing) in the editor. Then your code just gets a reference to that already-created Text, and sets the text property at runtime.

    If you don't know how many texts you're going to need, you can use Instantiate to clone them (or instantiate a prefab) at runtime. And then you'll either need to use something like a VerticalLayoutGroup to arrange them, or you'll have to come to grips with RectTransform to learn how to position them dynamically from code.

    Finally, I recommend you don't use Text any more. Add the TextMeshPro package to your project, and use a TextMeshProUGUI everywhere you would have used Text prior to 2017 or whatever. TextMeshPro is better than the built-in Text in every way.
     
    stain2319 and Schneider21 like this.
  3. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,190
    Just be aware that if you care about learning the latest to the exclusion of learning the old that UnityEngine.UI is itself to be replaced by UnityEngine.UIElements.

    https://docs.unity3d.com/Packages/com.unity.ui@1.0/manual/index.html
     
  4. Valynna

    Valynna

    Joined:
    Apr 1, 2021
    Posts:
    39
    In the end I got something to work, but for some reason the text is all blurry?

    This is what I call in the awake()

    Code (CSharp):
    1.     void awake_UI()
    2.     {
    3.         UI_canvas = new GameObject("UI Canvas");
    4.         UI_canvas.AddComponent<Canvas>();
    5.         UI_canvas.AddComponent<CanvasScaler>();
    6.         UI_canvas.AddComponent<GraphicRaycaster>();
    7.     }
    8.  
    9.     void awake_UIfps()
    10.     {
    11.         UI_fps = new GameObject("UI FPS");
    12.         UI_fps.AddComponent<Text>();
    13.         UI_fps.transform.parent = this.transform;
    14.         UI_fps.layer = 5;
    15.  
    16.         Font ArialFont = (Font)Resources.GetBuiltinResource(typeof(Font), "Arial.ttf");
    17.         UI_fps.GetComponent<Text>().font = ArialFont;
    18.         UI_fps.GetComponent<Text>().material = ArialFont.material;
    19.     }
    This is what I call in the start()

    Code (CSharp):
    1.     void init_UI()
    2.     {
    3.         Canvas canvas = UI_canvas.GetComponent<Canvas>();
    4.         canvas.worldCamera = Main_Camera.GetComponent<Camera>();
    5.     }
    6.     void init_UI_fps()
    7.     {
    8.         Text ui_text = UI_fps.GetComponent<Text>();
    9.         ui_text.text = "FPS Text INIT";
    10.         UI_fps.transform.parent = UI_canvas.transform;
    11.     }
    and it kind of works? But I think there's something wrong with some of the settings because like I said - the text is super blurry and not at all sharp like I imagine it should be.

    To clarify - the thing I need to fix is somewhere in the canvas render mode. But I haven't figured out what to fix yet or how.
     
    Last edited: Apr 22, 2021
  5. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    Have you played with the UI elements manually in edit mode first? It's much easier to see how they work and mess with settings to find out what looks best.

    In general, you'll want to ensure your Canvas's Canvas Scaler component is set to "Scale With Screen Size" and pick a Match property that works best for you (I prefer 1: fully set to Height) and increase your Reference Resolution to something practical like 1920x1080.

    If you need text items to be rendered to a small part of the screen, you can try increasing the item's font size and scaling it down. This feels super hacky to me, but it often gets you a clearer result. I think this is mostly applicable to world space canvases, though.