Just Shadow Just Shadow - 1 year ago 122
C# Question

How to show 3D text notification/toast while in game

Is there any simple way to show text notification in front of the camera (while in the game) and make it follow the camera while the player is moving?

We are creating a game where the player can give commands with voice, and when the command is recognized, some text notification must be shown (like toast notifications in Android).

I know about text meshes and that we can put it in front of the camera and show/hide it, but we need it to be done programmatically.

Answer Source

I ended up with creating a class which generates toast on fly.
Code is something like this (needs small re-factorizations. I'll update later):

using UnityEngine;

public class ToastText3D : MonoBehaviour
    public static ToastText3D Instance { get; private set; }

    private static bool isShowingTextMessage;
    private static GameObject textMeshGameObject;

    // Preventing instantiation of class by making constructor protoected (or private)
    protected ToastText3D() { }

    private void Awake()
        // Check if instance already exists
        if (Instance == null)
            // if not, set instance to this
            Instance = this;
        else if (Instance != this)
            // Then destroy this. This enforces our singleton pattern, meaning there can only ever be one instance of a GameManager.

        // Sets this to not be destroyed when reloading scene

    private void Update()
        if (!isShowingTextMessage)

        var headPosition = Camera.main.transform.position;
        var gazeDirection = Camera.main.transform.forward;

        float distanceFromCamera = 2; // TODO: Move this to const

        Vector3 desiredPosition = headPosition + gazeDirection * distanceFromCamera;
        textMeshGameObject.transform.position = desiredPosition;

        // Rotate the object to face the user.
        Quaternion toQuat = Camera.main.transform.localRotation;
        toQuat.x = 0;
        toQuat.z = 0;
        textMeshGameObject.transform.rotation = toQuat;

    // Returns current text mesh or creates new one if there is no
    private TextMesh getCurrentTextMesh()
        if (!textMeshGameObject)
            textMeshGameObject = new GameObject();

        TextMesh curTextMesh = textMeshGameObject.GetComponent(typeof(TextMesh)) as TextMesh;
        if (!curTextMesh)
            // TODO: Make constants
            curTextMesh = textMeshGameObject.AddComponent(typeof(TextMesh)) as TextMesh;
            MeshRenderer meshRenderer = textMeshGameObject.GetComponent(typeof(MeshRenderer)) as MeshRenderer;
            meshRenderer.enabled = true;
            curTextMesh.anchor = TextAnchor.MiddleCenter;
            curTextMesh.alignment = TextAlignment.Center;
            curTextMesh.fontStyle = FontStyle.Bold;
            curTextMesh.fontSize = 20;

            curTextMesh.transform.localScale = new Vector3(0.02f, 0.02f, 0.02f);

        return curTextMesh;

    public void Show3DTextToast(string textToShow, int timeout = 5)
        if (timeout < 0 || textToShow == "")

        TextMesh curTextMesh = getCurrentTextMesh();

        curTextMesh.text = textToShow;

        isShowingTextMessage = true;

        // Canceling message hiding invokation if there was any
        CancelInvoke("Hide3DTextToast"); // TODO: Move function name to const
        // Hiding text if there is any timeout
        if (timeout != 0)
            Invoke("Hide3DTextToast", timeout);

    public void Hide3DTextToast()
        isShowingTextMessage = false;

Now all we need is to call function Show3DTextToast by passing him text and interval.

ToastText3D.Instance.Show3DTextToast("Text Message", 10);
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download