Speech Bubbles in 2D that appears relative to 3D Space?

I am thinking about a specific way of showing dialogue in an RPG that I want to make. But I have a hard time imagining how I am going to achieve it.
Basically, speech bubbles should appear above a characters head in 3D but the Speech Bubble itself only exist in 2D Space (probably on the Canvas). If you have ever played a game like FF9 you’ll see what I mean:

As you see in this picture, the speech bubble appears above the characters head but the speech bubble itself exists on a 2D plane because regardless of the 3D characters position and scale the bubble is always the same size and always appears above a characters head correctly.

Any idea on how to approach this?

First idea: Create a world canvas and make it behave like a billboard by always rotating it towards the camera. Probably the easiest way, but might not look as good.

Second idea: Render the dialogue panel on your standard canvas, and have its pivot point at the tip of the thingy pointing towards the character. Add a script, which knows who the current bubble belongs to and make it WorldToScreenPoint some kind of attach point of the character. You should be able to just translate any point in world space into screen coordinates and position the bubble accordingly. This should also look good when rotating the camera.

1 Like

I think your second idea would probably the better of the two, but I can’t visualize in my head how I’d go about it still. Hmm ._.

I’m not 100% sure, but with the second idea don’t you also have to deal with scaling?

I’d say go with the world space canvas first. I think it will look fine, it’ll integrate properly with the world, and you don’t have to do any tricky math.

But will the bubble always have the same scale then?

As a world space, I think it’ll be effected by distance. I could be wrong, though. But if I’m right, then it won’t be the solution you’re looking for

I would really go with WorldToScreenPoint, it’s only one line to get you started:

transform.position = Camera.main.WorldToScreenPoint(character.position);

Create an overlay or camera canvas. Add the dialogue panel to it. Add a script with the above line. Get a reference to the character transform attach point. Then call in update or whenever things change. The panel will follow the character position on screen, but will always remain the same size, which you want, since the text should not be affected. The only thing to add to the system would be to make it smart enough to flip left or right depending on whether the character is on the left or right half of the screen (same technique use Screen.width and WorldToScreenPoint to check). Also you probably want to prevent the panel from ever leaving the screen, so put in another if WordToScreenPoint position > Screen.width - padding, then return; or something similar.

I don’t enough time to build a complete example right now, but I’m sure you can get started. If you have any more specific questions, just ask :wink:

1 Like

The second proposed solution is the one that should be pursued. World space UI’s are great for UI elements that should be positioned in the world, which means that they’ll have rotation and scale problems that need to be accounted for.

A simple world point to screen point call is an easy way to get an anchor point in a 2D UI canvas, which can be used to center the dialog box. It’s a lot easier to do this than to compensate for rotation and scaling of a world space canvas.

Yeah I don’t need 3D rotation or scaling at all for the Bubble. It will be the same scale every time and it can appear pretty much anywhere that the camera can see but it will appear above or below a characters head and the character exists in 3D.