- Home /
 
how can I add a 2D label to a 3D GameObject?
Hello, I have a number of GameObjects in an array, in varying number, and I want to add a UI label at some position over them. I want to do this by script, because my objects may change. I have tried the following, with a Canvas and attaching the script to the main camera, and I see the sphere, but no label is shown. Am I missing something obvious?
Thanks.
 using UnityEngine;
 using UnityEngine.UI;
 
 public class Bug : MonoBehaviour
 {
   Canvas canv;
   GameObject[] obj=new GameObject[100];
   Text objlabel;
 
   void Start()
     {
       canv = GameObject.Find("Canvas").GetComponent<Canvas>();
       Camera.main.transform.position = new Vector3(5, 5, -10);
       obj[0] = GameObject.CreatePrimitive(PrimitiveType.Sphere);
       obj[0].transform.position = new Vector3(-7.5f,6.0f,1.4f);
       obj[0].SetActive(false); // hide the sphere
       
       GameObject golab=new GameObject("Lab1");
       objlabel=golab.AddComponent<Text>();
       objlabel.text="XXXXX";
       objlabel.transform.SetParent(canv.transform);
 
       Vector3 namePos=Camera.main.WorldToScreenPoint(obj[0].transform.position);
       objlabel.transform.position=namePos;
     }
 
   void Update()
     {}
 }
 
 
              An auxiliary question is how I can set the canvas to adjust to the main camera view?
Answer by CmdrZin · Jan 29, 2021 at 07:46 PM
Here's some code that I use for that.
         // Add namePlate here after instaniation.
         namePlate = new GameObject("NamePlate");
         namePlate.AddComponent<TextMesh>();            // To display name.
         // Adjust position and settings.
         TextMesh textMesh = namePlate.GetComponent<TextMesh>();
         if (textMesh != null)
         {
             Debug.Log("Adding Nameplate");
             textMesh.transform.position = player.transform.position + new Vector3(0, 1.3f, 0);  // elevate y
             textMesh.transform.rotation = player.transform.rotation * new Quaternion(0, 180.0f, 0, 0);  // turn it around
             textMesh.characterSize = 0.2f;
             textMesh.fontSize = 10;
             textMesh.alignment = TextAlignment.Center;
             textMesh.anchor = TextAnchor.MiddleCenter;
             textMesh.color = Color.white;
             textMesh.text = id;     // Set the name text to the network id string.
         }
         // Now set the new Player object as its parent.
         namePlate.transform.parent = player.transform;
 
 
              Thanks. This works, but the problem is that the size of the text depends on the distance of the GameObject. I really would like to add some text in 2D at a constant distance in front of the camera and at some position corresponding to a 3D object. This is why I had initially used Camera.main.WorldToScreenPoint and a Canvas.
Answer by roegel · Jan 30, 2021 at 12:02 PM
Thanks, here is my improved version, without a Canvas:
 public class Bug2 : MonoBehaviour
 {
   GameObject[] obj=new GameObject[100];
   TextMesh objlabel;
 
   void Start()
     {
       Camera.main.transform.position = new Vector3(5, 5, -10);
       obj[0] = GameObject.CreatePrimitive(PrimitiveType.Sphere);
       obj[0].transform.position = new Vector3(-7.5f,6.0f,1.4f);
       obj[0].SetActive(true); // if false, hide the sphere (and the label)
       
       GameObject golab=new GameObject("Lab1");
       objlabel=golab.AddComponent<TextMesh>();
       objlabel.text="Sphere";
       objlabel.alignment = TextAlignment.Center;
       objlabel.anchor = TextAnchor.MiddleCenter;
       objlabel.color = Color.red;
 
       objlabel.transform.parent=obj[0].transform; 
       objlabel.transform.position=obj[0].transform.position+new Vector3(0,2,0);
     }
 
   void Update()
     {}
 }
 
 
              Your answer