Search code examples
unity-game-engine

How do I draw a black rectangle with the size of a text mesh in Unity Engine?


I have a TextMesh in UnityEngine which displays a text inside my game scene of a 2D platformer game.

I now want to add a black background rectangle to that white text. It has to have the same size as the text (plus some padding).

This is how I tried creating it

Renderer textRenderer = textMesh.GetComponent<Renderer>();
Vector3 textSize = textRenderer.bounds.size;

GameObject result = new GameObject("BackgroundRectangle");
SpriteRenderer spriteRenderer = result.AddComponent<SpriteRenderer>();

Texture2D texture = new Texture2D(1, 1);
texture.SetPixel(0, 0, Color.black);
texture.Apply();

Rect rect = new Rect(0, 0, textSize.x + 0.3f, textSize.y + 0.1f);
Vector2 pivot = new Vector2(0.5f, 0.5f);
Sprite sprite = Sprite.Create(texture, rect, pivot);
spriteRenderer.sprite = sprite; 

spriteRenderer.transform.localScale = new Vector3(textSize.x + 0.3f, textSize.y + 0.1f, 1.0f);       
result.transform.localScale = new Vector3(textSize.x + 0.3f, textSize.y + 0.1f, 1.0f);

This does not draw anything. If I experiment with

Texture2D texture = new Texture2D(1, 1);

and set it to e.g.

Texture2D texture = new Texture2D(100, 100);

it draws a rectangle. So I guess I have to use it that way? Or is there any other way I can fix it?

The problem I have with setting the Texture dimensions is that the text bounds are in engine units while the texture dimensions are in pixels.

Using a 3D Quad also works. But since this is a 2D game I want to put everything in a proper sorting layer to get the correct drawing order in all cases. And this is not possible with 3D objects.

Also tried to use GenAI to fix it, but that thing has no clue either.


Solution

  • Sprite.Create has more parameters, among them the pixelsPerUnit!

    Per default this is afaik 100f, meaning that e.g. a Texture2D with dimensions 100 x 100 will result in a square with world unit dimensions of 1 x 1. But you can basically chose and pass in any

    So this should be enough information to calculate the required pixel dimensions by just doing

    var backgroundPixelSize = textSize * desiredPixelsPerUnit;
    

    and then pass in the same factor into

    Sprite sprite = Sprite.Create(texture, rect, pivot, desiredPixelsPerUnit);