[VERY URGENT 4Hours LEFT!]Displaying other's speech bubble

Hi!

I’m currently trying to make speech bubble when people connected to the game type something on chat window.

I was able to make myself a speech bubble which hovers above my character which works fine, but thing is when other people chats and when speech bubble appears, it doesn’t quite get positioned properly according to their position through my camera’s sight. especially it doesn’t work when they go out of my sight and stuff.

So could anyone please help?! I’ve been trying this for such a long time and now I don’t have much time left…

I will really be appreciated if anyone come up with well modified code of below:

//locks gui text to objects position 
//doesn't work perfectly unless orthographic camera chosen 
var chatWindow: ChatWindow_test; //to refer ChatWindow_test script
var chatWinObj: GameObject; //to store ChatWindow Object found.

//GUI Styles and Skins
private var customGuiStyle : GUIStyle; 
public var chatfont : Font; 
public var defaultGuiSkin :GUISkin;

//callout positoin info
var screenPosition: Vector3;
var offsetX = 100; //try to correct x position 

var callouts: Texture2D; //texture of callout

var textAlign: TextAnchor;
var chatWrap: boolean;

public var bubbleText =""; //text to be appeared on callouts

var chatLines="";
var playerName="";

var calloutTarget:GameObject;

function Start()
{
	//set gui styles
	customGuiStyle = new GUIStyle(); 
	customGuiStyle.font = chatfont; 
	//set chatwindow
	chatWinObj = GameObject.Find("ChatWindow");
	chatWindow = chatWinObj.GetComponent("ChatWindow_test");
}

function Update()
{	
	bubbleText = chatWindow.bubbleChat; //update text from chatwindow_test every frame
}


function OnGUI (){   
	if(networkView.isMine)
	{
		if(bubbleText != "") //something has been stored on bubble text = user typed something
		{
			GUI.skin = defaultGuiSkin; //apply skin
			
			//color, callout, alignment and textwrapping
			customGuiStyle.normal.textColor = Color(1.0, 1.0, 0.0); 
			customGuiStyle.normal.background = callouts;
			customGuiStyle.alignment = textAlign;
			customGuiStyle.wordWrap = chatWrap;
			
			//gui position
			screenPosition = camera.main.WorldToScreenPoint(transform.position); 
			GUI.Box(Rect(screenPosition.x - offsetX, screenPosition.y -60, 200, 100),bubbleText,customGuiStyle); 
		}
		var playerInfo = gameObject.name;
		networkView.RPC("showCallouts", RPCMode.OthersBuffered, playerInfo, bubbleText);
	} else {
		if(playerName !=""  chatLines !="")
		{
			
			calloutTarget = GameObject.Find(playerName);
			GUI.skin = defaultGuiSkin; //apply skin
			
			//color, callout, alignment and textwrapping
			customGuiStyle.normal.textColor = Color(1.0, 1.0, 0.0); 
			customGuiStyle.normal.background = callouts;
			customGuiStyle.alignment = textAlign;
			customGuiStyle.wordWrap = chatWrap;
			screenPosition2 = camera.main.WorldToScreenPoint(calloutTarget.transform.position); 
			GUI.Box(Rect(screenPosition2.x  - offsetX, screenPosition2.y-60, 200, 100),chatLines,customGuiStyle); 
			
		}
	}
}

@RPC
function showCallouts(playInfo:String, chatWords:String)
{
	playerName = playInfo;
	chatLines = chatWords;
}

Your custom GUIStyle probably needs to have it’s alignment set to MiddleCenter. You also need to adjust for the width and height of your text. Finally, you can use Mathf.Clamp to keep your text on screen:

var myGUI : GUIStyle; //make sure GUI Alignment is MiddleCenter!
var textWidth : float;
var textHeight : float;
var message = "Hello World!";
private var screenPosition : Vector3;

function OnGUI(){
	screenPosition = camera.main.WorldToScreenPoint(transform.position);
	//adjust for text width  height, and clamp to the screen
	screenPosition.x = Mathf.Clamp(screenPosition.x - textWidth/2.0, textWidth, Screen.width - textWidth);
	screenPosition.y = Mathf.Clamp(screenPosition.y - textHeight/2.0, textHeight, Screen.height - textHeight);
	
	GUI.Label(Rect(screenPosition.x, screenPosition.y, textWidth, textHeight), message, myGUI);
}

What happens in 4 hours? Your game goes on sale, or your homework is due? :wink:

Hmm… I just tested it and forgot you need to reverse the y axis. Subtract screenPosition.y from Screen.height. I also made a few other adjustments to get the GUI I was using to properly clamp to the screen:

	screenPosition.x = Mathf.Clamp(screenPosition.x - textWidth/2.0, 0, Screen.width - textWidth);
	screenPosition.y = Screen.height - Mathf.Clamp(screenPosition.y - textHeight/2.0, textHeight, Screen.height);

my boss is gonna demonstrate with it four hours later… :frowning:

I don’t know what your code really does…
I tried applying your code into my script,
but it still doesn’t get displayed well in proper position. (and doesn’t follow player who displayed the speech bubble either)

As I said earlier, I’m fine with displaying my OWN speech bubble. The thing is that when someone else in the network types the chat and speech bubble appears, it doesn’t get displayed in the proper position from my perpective view.

I have to fix this “else” part where it takes the role of displaying speech bubble from other players…

 } else { 
      if(playerName !=""  chatLines !="") 
      { 
          
         calloutTarget = GameObject.Find(playerName); 
         GUI.skin = defaultGuiSkin; //apply skin 
          
         //color, callout, alignment and textwrapping 
         customGuiStyle.normal.textColor = Color(1.0, 1.0, 0.0); 
         customGuiStyle.normal.background = callouts; 
         customGuiStyle.alignment = textAlign; 
         customGuiStyle.wordWrap = chatWrap; 
         


screenPosition2 = camera.main.WorldToScreenPoint(calloutTarget.transform.position); 
         GUI.Box(Rect(screenPosition2.x  - offsetX, screenPosition2.y-60, 200, 100),chatLines,customGuiStyle); 
          
      }

I currently use RPC function to send information about which player has displayed its speech bubble and what he/she had typed.

Then this part…
screenPosition2 = camera.main.WorldToScreenPoint(calloutTarget.transform.position);

I wrote this code because I thought I have to determine other player’s speech bubble accroding to my main camera’s view.

When I play the game, other person’s speech bubble follows well horizontally but not vertically.

May be few minutes later - I might just forget it…
who cares about speech bubbles anyway?! My chat window works at least…

hey I just tried the one you posted again
(what a timing huh - right after posting that your code doesn’t seem to work…)

	if(playerName !=""  chatLines !="")
		{
			
			calloutTarget = GameObject.Find(playerName);
			GUI.skin = defaultGuiSkin; //apply skin
			
			//color, callout, alignment and textwrapping
			customGuiStyle.normal.textColor = Color(1.0, 1.0, 0.0); 
			customGuiStyle.normal.background = callouts;
			customGuiStyle.alignment = textAlign;
			customGuiStyle.wordWrap = chatWrap;
			//screenPosition2 = camera.main.WorldToScreenPoint(calloutTarget.transform.position); 
			 
			screenPosition2 = camera.main.WorldToScreenPoint(calloutTarget.transform.position); 
   //adjust for text width  height, and clamp to the screen 
	screenPosition2.x = Mathf.Clamp(screenPosition2.x - 200/2.0, 0, Screen.width - 200); 
   screenPosition2.y = Screen.height - Mathf.Clamp(screenPosition2.y - 100/2.0, 100, Screen.height);
    
			GUI.Box(Rect(screenPosition2.x, screenPosition2.y, 200, 100), chatLines, customGuiStyle); 
			//GUI.Box(Rect(screenPosition2.x  - offsetX, screenPosition2.y-60, 200, 100),chatLines,customGuiStyle); 
			
		}

This is how I applied your code into my script

and the speech bubble made by other player follows its maker well but the speech bubble is displayed below the character and when character moves out of my sight, it doesn’t disappear with character but stuck on the edge of the screen.

I wonder why?

Well, I told you what it does. It adjusts for the width and height of the bubble and clamps the position on screen (so if a player moves off screen, their text bubble remains).

It’s not a replacement for your code, it just an example to show you what SHOULD work. See my second post for a correction that fixes vertical movement.

Makes sense to me. But I’m not sure how Unity handles cameras and networked games. You might need a reference to the player’s camera.

Is it reversed? If so, subtract screenPosition.y from Screen.height.

Just a quick question. Is you game 2D? I noticed your code states it only works in orthographic in the comments.

This might not be a solution, but I would have a dummy node attached to the characters that floats above their head (or wherever you want the text bubble). Then use this as your point for the GUI position. Convert the 3D position to 2D screen space and setup your GUI.

There is some good wiki code for doing something like this. I haven;t used it but someone pointed me at it when I had a similar problem to yours:

It might help if you can post a screen shot of the kind of effect you want. Does not have to be from your game - just an example from another game.

I’ve been doing something similar in my project, but without seeing exactly what you’re after it’s tough to know how to help solve the problem.

Also - I’m not using Unity GUI - just GUITexture/GUIFont stuff.

I thought that was the behavior you wanted. If not, remove the Mathf.Clamp stuff.

So you’d just have:

	screenPosition.x = screenPosition.x - textWidth/2.0;
	screenPosition.y = screenPosition.y - textHeight/2.0;

Or in your case:

screenPosition2.x = screenPosition2.x - 200/2.0; 
screenPosition2.y = screenPosition2.y - 100/2.0;