Many games show dialogue with a popup speech bubble, or prompt you to press an action button when you approach an object. In this tutorial I’ll show you how to create a popup UI object that can be used for any kind of popup need in your Unity game, using Unity’s flexible UI system.
Here’s how it will look in a game:

There are countless uses for world space UI, such as buttons that provide interaction for certain objects, helper UI showing the player what button to press, and much more.
This tutorial is in 2D, but I’ve included an extra script required to get the functionality working properly in 3D. A full demo Unity project is linked at the end, including samples in 2D and 3D.
What we’ll be doing
We’ll use Unity’s UI system in ‘world space’ mode to show UI canvases within the game world (rather than overlaying the whole screen like a menu or control buttons).
This demo will use characters that will talk to the player via speech bubbles when the player approaches.
The great thing about using UI like this is that you can dynamically change the UI very easily. The character needs to say something different? Just change the text in the UI Text component.
Start the Project
Start up Unity and create a new project with 2D settings.
Next, build up a character who will talk to the player:
- Add an empty GameObject to the scene and call it ‘NPC’ (non-player character).
- Give the NPC a SpriteRenderer component and add a sprite of your choosing.
- Add a UI Canvas to NPC (right-click NPC in the Hierarchy > UI > Canvas).
- Select NPC’s canvas in the Hierarchy by clicking it.
World Space Canvas Settings
Change the canvas’s settings to match mine in the image below. You may want to adjust yours slightly depending on the size of your NPC sprite or screen setup, so take my scale and size values as guides, not definitive. The settings to set are within the red boxes.
- Set the canvas Render Mode to World Space.
- Change the canvas scale to 0.05 on all axes.
- Change the canvas position to [0,0,0] (i.e. the same position as the parent GameObject)
- Adjust the width and height to about 200×100.
When your settings are right, you should see something similar to this in the Scene window when you select the canvas in the Hierarchy:

The canvas is the grey box sitting above the giraffe’s head. The speech text will go inside the canvas. If you don’t get a suitable size/shape for the canvas, tweak those settings and make sure the position is [0,0,0].
Add Some Text
Add a UI Panel component to the NPC’s canvas.
You can leave the panel at the default grey shading, or even better add a speech bubble image to its Image component like I’ve used (you can use the image in the sample project). If you use an image you might need to adjust the canvas positioning so it looks right. You can also tint the panel to give your speech bubble more character.

Next, right-click the Canvas component and select UI > Text to add a Text component. Add some text, then tweak the size of the Text component to ensure it looks good. I recommend centering the text and using a fun font.

Customisable
You’ve created the speech bubble with some hard-coded text, but remember that the benefit of using a canvas here is that you can easily change the text via scripting (e.g. if your player will be having conversations with other characters).
A Fun Example
World space UI is great by itself, but let’s make it more fun with an example. We’ll make the speech bubble display only when the player is close to the NPC character.
Here’s what we need to do:
- Create a simple player that can move around the screen.
- Detect when the player is near to the NPC and turn the canvas on.
Create the Player
- Add a new empty GameObject to the scene and call it ‘Player’.
- Add a sprite to Player (anything you want).
- Add a Rigidbody2D (this is required to enable trigger collider physics)Set the gravity scale to 0. This is required in this sample because of the way I’m setting up movement; it has nothing to do with the actual UI display technique.
- And a CircleCollider2D (you can use any collider shape, but I used a circular sprite, so a circle was best).
Finally, you need to create a new C# script called DemoController.cs, and add it to the player. Here is the full script code. It simply moves the player around on X and Y axes according to keyboard or game controller input:
using UnityEngine;
using System.Collections;
public class DemoController : MonoBehaviour {
[SerializeField]
private float speed;
enum MoveDir
{
None,
Up,
Down,
Left,
Right
}
void Update()
{
GetInput();
}
void GetInput()
{
if (Input.GetAxis("Horizontal") > 0.2f)
{
Move(MoveDir.Right);
}
if (Input.GetAxis("Horizontal") < -0.2f)
{
Move(MoveDir.Left);
}
if (Input.GetAxis("Vertical") > 0.2f)
{
Move(MoveDir.Up);
}
if (Input.GetAxis("Vertical") < -0.2f)
{
Move(MoveDir.Down);
}
}
void Move(MoveDir moveDir)
{
var movement = Vector3.zero;
switch (moveDir)
{
case MoveDir.Down:
movement = new Vector3(0, -1f,0);
break;
case MoveDir.Up:
movement = new Vector3(0, 1f,0);
break;
case MoveDir.Left:
movement = new Vector3(-1f, 0, 0);
break;
case MoveDir.Right:
movement = new Vector3(1f, 0, 0);
break;
default:
return;
}
transform.Translate(movement*speed * Time.deltaTime);
}
}
Test your scene. You should be able to move the player around the screen with the arrow keys or a gamepad.
Update your NPC
Currently, the NPC’s speech bubble is visible. We want it to display only when the player is nearby. Let’s make a few adjustments to the NPC to make this happen.
Add a CircleCollider2D to the NPC GameObject.
- Make the collider larger than the sprite so it acts as a ‘zone’ that triggers speech when the player enters.
- Tick the Is Trigger box on the component so that the collider is in trigger mode.
Here’s the size I used for my collider (the green circle):

Script the Interaction
Create a new script called InteractiveObject.cs and paste in the following code:
using UnityEngine;
using System.Collections;
public class InteractiveObject : MonoBehaviour
{
[SerializeField]
Canvas messageCanvas;
void Start()
{
messageCanvas.enabled = false;
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.name == "Player")
{
TurnOnMessage();
}
}
private void TurnOnMessage()
{
messageCanvas.enabled = true;
}
void OnTriggerExit2D(Collider2D other)
{
if (other.name == "Player")
{
TurnOffMessage();
}
}
private void TurnOffMessage()
{
messageCanvas.enabled = false;
}
}
Basically it turns the canvas component on when the player enters the trigger zone and off when the player leaves. The canvas is turned off when the scene starts (but I find it useful to have the canvas on by default when working in the Unity editor).
Add a copy of that script to your NPC GameObject.
Select the NPC, then drag its Canvas from the Hierarchy into the empty Message Canvas slot on the Interactive Object script in the Inspector so the script knows which canvas to turn on and off.
Test the Scene
Now test the scene. If all has gone according to plan your NPC character should speak when the player object gets close to it:

World space in 3D
To adapt this to 3D, you need one addition. In 3D games, a canvas could be facing in any direction, so the player won’t always see it. To get around this, you can add a short script to turn the canvas to face the camera so it’s always visible. Of course you’ll also replace the 2D physics with 3D equivalents. Attach the script below to any object with a world space UI if you want it to always face the player’s view (i.e. the camera).
using UnityEngine;
using System.Collections;
public class SpeechBubbleRotate : MonoBehaviour
{
Transform cameraTransform;
void Start()
{
cameraTransform = Camera.main.transform;
}
void Update()
{
transform.rotation = Quaternion.LookRotation(transform.position - cameraTransform.position);
}
}
Download
Here’s the full sample project including examples in 2D and 3d. All the art in the project is public domain (mostly from Kenney), as is the code, so do with it what you like.
Next Steps
Now that you know how to use a world space canvas to display UI inside your game area, you can use the technique in many ways. Here are some things you can try:
- Add interactive UI (e.g. buttons) to the canvas.
- Only show the UI if the player is in the trigger area and presses a button.
- Build a fancy UI with lots of different UI elements to test out the functionality.
Hi there,
Thank you for your tutorial. I have a follow-up question. My project is developed in 3D, and I would like to add a pop-up text on the UI (canvas) alongside a 3D object which is created when player created it.
To better illustrate my question, let say my project is SimCity, and my expected result is some numbers pop up above the building I built. Thank you very much.
Allen
You don’t need to do anything special in this scenario. Just make sure you have a canvas as a child of the prefab that is created. Place the canvas according to where you want it to display. Use the script from the sample project to make sure the canvas is always facing the camera or else the canvas won’t always be visible in 3D.
Nice tutorial ,
thanks.
i can use it for my Unity Project
Hi.
Wow Very Nice! Thank you so much for sharing great post.
Hey, great tutorial. I have a problem though. I get a error message saying that the messageCanvas isn’t assigned and has a value of null. Maybe Unity has made changes since this was put up?
You probably missed this step:
“Select the NPC, then drag its Canvas from the Hierarchy into the empty Message Canvas slot on the Interactive Object script in the Inspector so the script knows which canvas to turn on and off.”
If that isn’t done, the messageCanvas will be null and give the error you have.
Fantastic tutorial! I have been working on my project for a week and nothing has worked until I tried this 😀 One question – how could I trigger a graphic to appear instead of text?
You can simply replace the UI Text component with an Image component and add the graphic to that.