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?
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:
my boss is gonna demonstrate with it four hours later…
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…
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.
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.