Dialog text above player's head?

I am trying to get my GUI Label to appear above my player but can’t get it quite right!
Now before you suggest the ObjectLabel on the unify wiki, I need it to do the opposite of that, where instead of attaching the gameobject to the text the text needs to be applied relative to the gameobject

heres what i have at the moment, but its awful!

Vector3 coords = Camera.main.WorldToScreenPoint(transform.position);
GUI.Label(new Rect(coords.x * Screen.width, (1 - coords.y )* Screen.height - 100,100,50), dialog);

although when you move on the y axis it goes a bit funny? Also I wouldn’t know for the life of me where to begin on working out how to clamp it to the screen!

This is infact how I would like to do it, using a GUI Text would not work for me.

Thanks in advance

Here is shorter way to do so (with less mathematics). First you create a new gameObject and add a TextMesh component and configure it with your desired text and fonts and style. You can do it in the Editor or write code to do so:

void Start() {
            GameObject sign = new GameObject("player_label");          
            sign.transform.rotation = Camera.main.transform.rotation; // Causes the text faces camera.
            TextMesh tm = sign.AddComponent<TextMesh>();
            tm.text = "put your text here. You can use some of the html attributes";
            tm.color = new Color(0.8f, 0.8f, 0.8f);
            tm.fontStyle = FontStyle.Bold;
            tm.alignment = TextAlignment.Center;
            tm.anchor = TextAnchor.MiddleCenter;
            tm.characterSize = 0.065f;
            tm.fontSize = 60;
}

Then, in the Update() method, place it above the player gameObject:

void Update() {
sign.transform.position = player.position + Vector3.up * 3f;  
}

You may ask why we didn’t made the sign gameObject a child of player gameObject instead of placing it above the player. The quick answer is that if the player rotates then the sign would rotate with it too because it’s a child of player gameObject. This is unwanted. We want the text to always facing the camera.

Ok so first I get the position of my character in relation to the camera

Vector3 characterPos = Camera.main.WorldToScreenPoint(characterObject.transform.position);

then i clamp the position inside the screen

characterPos = new Vector3(Mathf.Clamp(characterPos.x,0 + (windowWidth / 2),Screen.width - (windowWidth / 2)),
			                           Mathf.Clamp(characterPos.y,50,Screen.height),
			                           characterPos.z);

then i add my BeginArea positioned in relation to my character

GUILayout.BeginArea(new Rect((characterPos.x + offsetX) - (windowWidth / 2), (Screen.height - characterPos.y) + offsetY, windowWidth, windowHeight));

Whole code:

void OnGUI () {
    Vector3 characterPos = Camera.main.WorldToScreenPoint(characterObject.transform.position);

    characterPos = new Vector3(Mathf.Clamp(characterPos.x,0 + (windowWidth / 2),Screen.width - (windowWidth / 2)),
			                           Mathf.Clamp(characterPos.y,50,Screen.height),
			                           characterPos.z);

    GUILayout.BeginArea(new Rect((characterPos.x + offsetX) - (windowWidth / 2), (Screen.height - characterPos.y) + offsetY, windowWidth, windowHeight));

        // GUI CODE GOES HERE

    GUILayout.EndArea();
}

obviously this would need tweaking to make it perfect but this is just pseudo code to help anyone with this problem
good luck, i hope this helps

I’ve had problems with the Y being inverted before.

Vector3 coords = Camera.main.WorldToScreenPoint(transform.position);
coords.y = Screen.height - coords.y;
GUI.Label(new Rect(coords.x * Screen.width, (1 - coords.y )* Screen.height - 100,100,50), dialog);

You should be able to use Screen.width and Screen.height to clamp the position.

So you’re good now by using WorldToScreenPoint, all you need now is clamping? All you need do for that is:

Vector3 coords = Camera.main.WorldToScreenPoint(transform.position);
Rect r = new Rect(coords.x, Screen.height - coords.y - 100,100,50);
if (r.x < 0)
   r.x = 0;
else if (r.xMax >= Screen.width)
   r.x = Screen.width - r.width;
if (r.y < 0)
   r.y = 0;
else if (r.yMax >= Screen.height)
   r.y = Screen.height - r.height;