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

Best Method To Draw TTF Text Onto Screen From Within C# Script Code?

Discussion in 'Scripting' started by FallenAngelSoftware, Jun 29, 2021.

Thread Status:
Not open for further replies.
  1. FallenAngelSoftware

    FallenAngelSoftware

    Joined:
    Aug 12, 2018
    Posts:
    58
    Hi,

    Appreciate all the help the forum has given our development team...

    We about finished the sprite code core.
    We are now trying to implement a text core: drawing TTF text onto the screen only using C# script code.

    What would be the best method to do the above?
    Please look at our visualsCore.cs below:

    Thanks!

    Jesse

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. static class visualsCoreGlobal
    6. {
    7.     public static Sprite[] Sprites;
    8.     public static GameObject[] SpriteGOs;
    9.     public static SpriteRenderer[] SpriteRenderers;
    10.  
    11.     public static Font[] Fonts;
    12.  
    13.     public static int LoadSprite(int index, string fileName)
    14.     {
    15.         Sprites[index] = Resources.Load<Sprite>(fileName);
    16.         SpriteGOs[index] = new GameObject("Sprites[index]");
    17.         SpriteRenderers[index] = SpriteGOs[index].AddComponent<SpriteRenderer>();
    18.         SpriteRenderers[index].sprite = Sprites[index];
    19.  
    20.         return (1);
    21.     }
    22.  
    23.     public static int LoadAllSprites()
    24.     {
    25.         Sprites = new Sprite[1300];
    26.         SpriteGOs = new GameObject[1300];
    27.         SpriteRenderers = new SpriteRenderer[1300];
    28.  
    29.         LoadSprite(0, "Sprites/BG_ScreenFade");
    30.         LoadSprite(1, "Sprites/TS_Logo");
    31.  
    32.         return (1);
    33.     }
    34.  
    35.     public static int LoadAllFonts()
    36.     {
    37.         Fonts = new Font[1];
    38.        
    39.         Fonts[0] = Resources.Load<Font>("Fonts/Font_01");
    40.  
    41.         return (1);
    42.     }
    43.  
    44.     public static int DrawSprite(int spriteIndex, float screenX, float screenY, float screenZ, float scaleX, float scaleY, float rotation, float red, float green, float blue, float alpha)
    45.     {
    46.         float xPos = (SpriteRenderers[spriteIndex].bounds.size.x) / (640.0f/screenX);
    47.         float yPos = (SpriteRenderers[spriteIndex].bounds.size.y) / (360.0f/screenY);
    48.         SpriteRenderers[spriteIndex].transform.localPosition = new Vector3(xPos, yPos, screenZ);
    49.         SpriteRenderers[spriteIndex].transform.localScale = new Vector3(scaleX, scaleY, 1.0f);
    50.         SpriteRenderers[spriteIndex].transform.Rotate(Vector3.forward * rotation);
    51.         SpriteRenderers[spriteIndex].color = new Vector4(red, green, blue, alpha);
    52.  
    53.         return (1);
    54.     }
    55.  
    56.     public static int DrawText(int font, string text, float screenX, float screenY, float screenZ, float scaleX, float scaleY, float rotation, float red, float green, float blue, float alpha, float redOutline, float greenOutline, float blueOutline, float alphaOutline)
    57.     {
    58.  
    59.         return (1);
    60.     }
    61.  
    62. }
    63.  
    64. public class visualsCore : MonoBehaviour
    65. {
    66.     // Start is called before the first frame update
    67.     void Start()
    68.     {
    69.        
    70.     }
    71.  
    72.     // Update is called once per frame
    73.     void Update()
    74.     {
    75.        
    76.     }
    77. }
    78.  
     
  2. FallenAngelSoftware

    FallenAngelSoftware

    Joined:
    Aug 12, 2018
    Posts:
    58
  3. RadRedPanda

    RadRedPanda

    Joined:
    May 9, 2018
    Posts:
    1,593
    I would just suggest creating a Canvas with a Text object (one that has a Text component, or TMP as that's what everyone uses). Easiest way is to just Instantiate a Prefab of a text object you've already made which has font size, color, and all that jazz. Incase you didn't know, you can render a Canvas in World Space, which lets it exist in the 3D space instead of attached to your screen (this includes rotation and stuff).

    upload_2021-6-29_7-59-10.png
     
  4. FallenAngelSoftware

    FallenAngelSoftware

    Joined:
    Aug 12, 2018
    Posts:
    58
    Hi,

    Thanks for the reply...

    We are trying hard to do everything from C# script code.
    Can you provide a small C# code example on what you think would be the best method to display text from C# ?

    Please refer to the above GitHub code repository to see what we are currently doing...
    Thanks!

    Jesse
     
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,762
    I don't need to look there. You are electing to forego 100% of the power and utility of Unity's entire UI and text rendering system, which is exposed at the GUI level, the TextMesh level, the UnityEngine.UI level, and now at the TextMeshPRO level... FOUR PLACES that the Unity engineering team have gone to MASSIVE lengths to make printing easy... and you're trying to avoid that.

    Why?

    You are going to really have to try hard with that. Wow. I can't even imagine how you would move from a TTF vector font to realize the shape, calculate the metrics, kerning, emphasis, all that just to strike the glyph bitmaps one pixel at a time, to finally rendering them with quads and consider that even something that would be worth doing in a game.

    If you're going to go that route, you might as well just write your own game engine really.
     
    bobisgod234 likes this.
  6. bobisgod234

    bobisgod234

    Joined:
    Nov 15, 2016
    Posts:
    1,042
    I don't really understand what the rationale is behind using Unity in such an un-Unity way. Your "DrawSprite" looks like an attempt to mimic immediate-mode rendering. If that is what you want, have you considered something like SFML instead?
     
    Kurt-Dekker likes this.
  7. FallenAngelSoftware

    FallenAngelSoftware

    Joined:
    Aug 12, 2018
    Posts:
    58
    Hi,

    I think I am adding a text through C# script code, but when I run the game no text is displayed?

    Please see code("DrawText" function) and screenshot below:

    Jesse

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5.  
    6. static class visualsCoreGlobal
    7. {
    8.     public static Sprite[] Sprites;
    9.     public static GameObject[] SpriteGOs;
    10.     public static SpriteRenderer[] SpriteRenderers;
    11.  
    12.     public static Font[] Fonts;
    13.  
    14.     public const int JustifyLeft = 0;
    15.     public const int JustifyCenter = 1;
    16.     public const int JustifyRight = 2;
    17.     public const int JustifyCenterOnPoint = 3;
    18.  
    19.     public static int LoadSprite(int index, string fileName)
    20.     {
    21.         Sprites[index] = Resources.Load<Sprite>(fileName);
    22.         SpriteGOs[index] = new GameObject("Sprites[index]");
    23.         SpriteRenderers[index] = SpriteGOs[index].AddComponent<SpriteRenderer>();
    24.         SpriteRenderers[index].sprite = Sprites[index];
    25.  
    26.         return (1);
    27.     }
    28.  
    29.     public static int LoadAllSprites()
    30.     {
    31.         Sprites = new Sprite[1300];
    32.         SpriteGOs = new GameObject[1300];
    33.         SpriteRenderers = new SpriteRenderer[1300];
    34.  
    35. //        LoadSprite(0, "Sprites/BG_ScreenFade");
    36. //        LoadSprite(5, "Sprites/BG_Title");
    37. //        LoadSprite(6, "Sprites/TS_Logo");
    38.  
    39.         return (1);
    40.     }
    41.  
    42.     public static int LoadAllFonts()
    43.     {
    44.         Fonts = new Font[1];
    45.        
    46.         Fonts[0] = Resources.Load<Font>("Fonts/Font_01");
    47.  
    48.         return (1);
    49.     }
    50.  
    51.     public static int DrawSprite(int spriteIndex, float screenX, float screenY, float screenZ, float scaleX, float scaleY, float rotation, float red, float green, float blue, float alpha)
    52.     {
    53.         float xPos = (SpriteRenderers[spriteIndex].bounds.size.x) / (640.0f/screenX);
    54.         float yPos = (SpriteRenderers[spriteIndex].bounds.size.y) / (360.0f/screenY);
    55.         SpriteRenderers[spriteIndex].transform.localPosition = new Vector3(xPos, yPos, screenZ);
    56.         SpriteRenderers[spriteIndex].transform.localScale = new Vector3(scaleX, scaleY, 1.0f);
    57.         SpriteRenderers[spriteIndex].transform.Rotate(Vector3.forward * rotation);
    58.         SpriteRenderers[spriteIndex].color = new Vector4(red, green, blue, alpha);
    59.  
    60.         return (1);
    61.     }
    62.  
    63.     public static int DrawText(int font, int size, string textString, float screenX, float screenY, float screenZ, int justification, float scaleX, float scaleY, float rotation, float red, float green, float blue, float alpha, float redOutline, float greenOutline, float blueOutline, float alphaOutline)
    64.     {
    65.         GameObject textGO = new GameObject("TextTest");
    66.  
    67.         Text text = textGO.AddComponent<Text>();
    68.         text.font = Fonts[0];
    69.         text.text = textString;
    70.  
    71.         float xPos = 1;
    72.         float yPos = 1;
    73.         text.transform.localPosition = new Vector3(xPos, yPos, screenZ);
    74.  
    75.         text.fontSize = size;
    76.         text.color = new Vector4(red, green, blue, alpha); ;
    77.  
    78.  
    79.         return (1);
    80.     }
    81. }
    82.  
     
  8. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,762
    There is a LOT more code than that to make a UnityEngine.UI.Text appear!

    To begin with, it has to be parented under a properly set-up Canvas, and have all the right RectTransform values on it and above it.

    Right-click add a Text into the scene yourself and compare. All the rest of that crud is auto-added by scripts in the UI package. You can see all that code and refer to it yourself by looking in the Package Mangler or on github.

    If you just want cheap and cheerful text, use a TextMesh object. Here's a package that does it for little rising score digits. But I warn you again, it will be a LOT of work to write an entire game around this sort of thing.
     

    Attached Files:

  9. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    8,992
    Kurt-Dekker likes this.
  10. FallenAngelSoftware

    FallenAngelSoftware

    Joined:
    Aug 12, 2018
    Posts:
    58
  11. FallenAngelSoftware

    FallenAngelSoftware

    Joined:
    Aug 12, 2018
    Posts:
    58
    Hi,

    Need a little more help.
    With text drawing working I can make most of the game(except audio).

    Horizontal justification of text is not working?
    https://github.com/SLNTHERO/TetriStory_110Percent/blob/main/Assets/Scripts/visualsCore.cs#L101

    Font size is acting weird?(size of 2 looks ok, but when size 3 the text is way too large?)
    https://github.com/SLNTHERO/TetriStory_110Percent/blob/main/Assets/Scripts/visualsCore.cs#L113

    Also I don't understand text positioning on the screen.
    Also would like an outline of text in any color, scaling of text, and rotation of text is technically possible...

    Any help would be appreciated, thanks!

    Jesse
     
  12. FallenAngelSoftware

    FallenAngelSoftware

    Joined:
    Aug 12, 2018
    Posts:
    58
  13. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,762
    Massive numbers of people all over the world use UnityEngine.UI to put text onscreen. Our company has 50+ people working in Unity every day doing this stuff. It's 99% of what we do when we're in Unity: make UI and presentation text.

    Coupled with all the bells and whistles of TextMeshPRO, UnityEngine.UI is really an AMAZINGLY powerful system, one that takes some effort to learn, but one that pays back huge dividends, particularly when you have engineers and artists on a team: the engineer mocks up the UI with white boxes, the artists go nuts cloning and skinning and "arting" it up.

    It's glorious. Embrace it. Welcome to 2021. Nobody has to write crappy boilerplate C# code to display text anymore. Unity3D is the best game engine ever.
     
  14. infernobirdy

    infernobirdy

    Joined:
    Feb 12, 2014
    Posts:
    2
    I don't really get why you seem to take it so personally that some ppl might want to use this tool in a different way than works for you. Sometimes you do not have a big art department. sometimes you dont want to use 100 GameObjects to put something on the screen. Sometimes you just want to call a method in C# to render simple text. You don't have to like it, but you also don't have to write a rant about how noone should ever want to do things differently.
     
  15. _geo__

    _geo__

    Joined:
    Feb 26, 2014
    Posts:
    1,115
    Sometimes those kind souls patiently answering dozens of beginner questions every day just have a bad day themselves or get triggered by a seemingly simple question. Especially if the person asking is just ignoring the advice given and displays an extra big amount of thickheadedness.

    The reasonable assumption made by kurt et all is that the OP wants to make a game not a game engine (as OP posted in an engine specific forum). The fastest way to get there is to actually USE the engine, not ignore it. The advice given was not only correct but it also would have helped the OP to avoid a lot of frustration which eventually led to them "giving up". It's a lose lose situation all around. And now you swoop in and try to troll. I assume you are having a bad day too, and that's okay. Go grab something to eat, it helps, really :)
     
    Kurt-Dekker and Schneider21 like this.
  16. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    8,969
    Closed for many reasons.
    1. just posting a project and asking people to "help" (write stuff for me)
    2. pretty much ignoring responses
    3. doing it wrong in the first place.
    4. "giving up" while people are trying to help.

    "sticking TTF on screen by just c#..." is very silly. Read through the learn section, understand how the UI/TMP works. it is simple/trivial to add text to screen programmatically. Very simple. None of it involves "Resources.Load<Font>("Fonts/Font_01");"
     
    _geo__ and Schneider21 like this.
Thread Status:
Not open for further replies.