How to render text not visible through my objects

Hello,
I am a complete beginner with Unity. I am currently trying to display a number on all the faces of my cubes based on their ID from their names. I could get a result from my script (see below), However, the text is visible through the cube, which makes it hard to read.

Then I tried several solutions:

I couldn’t make anything work. They asked to either create a custom shader from the Unity archive or to use TextMeshPro shader.

I created a shader from the one given in the Unity archive, linked it to a Material, and then to my TextMesh, but I got a black square or nothing.

If I change manually the Material to Liberation font material, I get a strange text:

Here is the code of my script:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class TextOnSide : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        // Get the cube's number from its name
        string cubeName = gameObject.name;
        string numberString = cubeName.Substring(cubeName.IndexOf("_") + 1);
        int cubeNumber;
        Material textMaterial;

        if (int.TryParse(numberString, out cubeNumber))
        {
            // Iterate through each face of the cube
            for (int i = 0; i < 6; i++)
            {
                // Create a TextMesh for each face
                GameObject textObject = new GameObject("Text" + i);
                textObject.transform.parent = transform;

                // Calculate position based on face normal
                Vector3 faceNormal = GetFaceNormal(i);
                textObject.transform.localPosition = faceNormal * 0.51f;

                // Rotate text to align with face normal
                Quaternion rotation = Quaternion.LookRotation(-faceNormal, Vector3.up);
                textObject.transform.localRotation = rotation;

                TextMesh textMesh = textObject.AddComponent<TextMesh>();
                textMesh.anchor = TextAnchor.MiddleCenter;
                textMesh.alignment = TextAlignment.Center;
                textMesh.text = cubeNumber.ToString();

                // Set font color to black
                textMesh.color = Color.black;

                // Adjust the size of the text based on the cube's size
                float textSize = Mathf.Min(transform.localScale.x, transform.localScale.y, transform.localScale.z) * 80f;
                textMesh.fontSize = (int)textSize;

                // Adjust character size for better clarity
                textMesh.characterSize = 0.1f;                

                // Create a new material using the OcclusionTextShader (those line are commented when the number are visible through the cube
                //textMaterial = new Material(Shader.Find("Custom/Text Shader")); // My own shader from the Unity archive
                //textMaterial = new Material(Shader.Find("TextMeshPro/Mobile/Distance Field"));
                //textMesh.GetComponent<Renderer>().material = textMaterial;
            }
        }
        else
        {
            Debug.LogError("Cube name does not contain a valid number.");
        }
    }

    // Helper method to get face normal based on face index
    Vector3 GetFaceNormal(int faceIndex)
    {
        Vector3[] faceNormals = { Vector3.up, Vector3.down, Vector3.forward, Vector3.back, Vector3.right, Vector3.left };
        return faceNormals[faceIndex];
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

What should I do to make the text not visible if it is behind my object? Thanks in advance. I have been trying for days, and I cannot manage to make it, even if it should not be that difficult.

PS: I am using Unity 2022.3.19

You’re better off using TextMeshPro instead.
Its basically a free official package, that adds a new component that’s essentially TextMesh but Enhanced.

Not only it’s not visible through objects, but in the material debug settings you can cull one of the faces, which means only one side of the text will be visible.

To do so, click on Window>Package Manager
Top Left, next to the “+”, click on the menu “Packages : Whatever” and select : “Unity Registry”
Then find “TextMeshPro” in the list, click on it, then the button “install”.

You’ll get a popup to install TMP essentials, install it.
if you don’t you can go to Window>TextMeshPro > Import TMP Essentials Resources.

You’ll have the TextMeshPro object in the hierarchy in 3D Objects >TextMeshPro.

Thank you for the answer. Indeed with TextMeshPro it worked better than with TextMesh!

For people interested, here is the updated code:

using UnityEngine;
using TMPro;

public class TextOnSide : MonoBehaviour
{
    void Start()
    {
        // Get the cube's number from its name
        string cubeName = gameObject.name;
        string numberString = cubeName.Substring(cubeName.IndexOf("_") + 1);
        int cubeNumber;

        if (int.TryParse(numberString, out cubeNumber))
        {
            // Create a Space Canvas for each cube 
            GameObject canvasObject = new GameObject("CubeSpaceCanvas");
            canvasObject.transform.SetParent(transform); // Set the cube as the parent
            canvasObject.transform.localPosition = Vector3.zero;
            Canvas canvas = canvasObject.AddComponent<Canvas>();
            canvas.renderMode = RenderMode.WorldSpace;

            // Iterate through each face of the cube
            for (int i = 0; i < 6; i++)
            {
                // Create a TextMeshPro for each face
                GameObject textObject = new GameObject("Text" + i);
                textObject.transform.SetParent(canvasObject.transform);

                // Calculate position based on face normal
                Vector3 faceNormal = GetFaceNormal(i);
                textObject.transform.localPosition = faceNormal * 0.51f;

                // Rotate text to align with face normal
                Quaternion rotation = Quaternion.LookRotation(-faceNormal, Vector3.up);
                textObject.transform.localRotation = rotation;

                TextMeshPro textMesh = textObject.AddComponent<TextMeshPro>();
                textMesh.rectTransform.anchorMin = Vector2.zero;
                textMesh.rectTransform.anchorMax = Vector2.one;
                textMesh.rectTransform.sizeDelta = Vector2.zero;
                textMesh.alignment = TextAlignmentOptions.Center;
                textMesh.text = cubeNumber.ToString();

                // Set font color to black
                textMesh.color = Color.black;

                // Adjust the size of the text based on the cube's size
                float textSize = Mathf.Min(transform.localScale.x, transform.localScale.y, transform.localScale.z) * 9f;
                textMesh.fontSize = (int)textSize;

                // Adjust character size for better clarity
                textMesh.characterSpacing = 0.1f; 
            }
        }
        else
        {
            Debug.LogError("Cube name does not contain a valid number.");
        }
    }

    Vector3 GetFaceNormal(int faceIndex)
    {
        Vector3[] faceNormals = { Vector3.up, Vector3.down, Vector3.forward, Vector3.back, Vector3.right, Vector3.left };
        return faceNormals[faceIndex];
    }

    void Update()
    {

    }
}