Unity Quickstart
In this Quickstart, you'll learn in minutes how to build your first web app using Unity that sends and receives a message, in addition to learning how to use status and presence events to enhance your real-time application.
Sample app Quickstart | SDK Getting Started |
---|---|
Unity Developer Path
Looking for Unity use-cases, white papers, and sample apps? Check out our Unity Developer Path.
PubNub Account
Sign in or create an account to create an app on the Admin Portal and get the keys to use in this Quickstart.
Download Sample App
You can clone the repository that contains the files you'll use in this Quickstart. Remember to replace the publish and subscribe key placeholders with your own keys.
https://github.com/pubnub/Unity-Realtime-Chat-Room-Tutorial
Project Setup
Download the Unity Hub. The Unity Hub is used to manage Unity versions and Unity projects you’re developing.
Once you’ve downloaded Unity Hub, open it and add any Unity Version equal to or older than 2018 LTS. The 2018 LTS version was used to create the tutorial app, but you can upgrade it if you wish.
Download or clone the Unity chat tutorial repo, and, in Unity Hub, go to the Projects tab, and click ADD.
If you’re using a Unity version newer than 2018 LTS then you’ll be asked to confirm you want to upgrade the project to a newer version of Unity. Click Confirm to continue.
Project upgrade errors
Upgrading the project may break the exact location of some UI elements, however the app will still work and you can change the UI to your preference. Once imported, there may be The type or namespace name 'TestTools' does not exist
errors in your console window.
You can fix the errors by going to Window > General > Test Runner. Click on the drop-down menu in the top right corner, enable playmode tests for all assemblies, and close all Unity windows and reopen your project.
Run the app
Open the
scripts/SendMessage
script by clicking on the script in the Unity project navigator and replace the myPublishKey and mySubscribeKey placeholders with your own PubNub publish and subscribe keys.Save your work and, in the Unity editor, navigate to
Assets/Scenes
open theRealtimeChat.unity
file and click the Run button.
You just created a real-time chat application in the Unity 3D game engine that sends and receives messages from the Unity Chat lobby using PubNub!
Walkthrough
Now that you have the demo app running, let’s take a deeper look at how it works. You do not have to perform the steps below for the quickstart to run - these sections are designed to inform you how the quickstart app works.
Include Unity SDK
You can include the PubNub SDK in any Unity app by downloading the latest PubNub Unity package and then importing that package into Unity by going to Assets -> Import Package -> Custom Package.
Once imported, you may notice you have some errors in your console window. To fix these errors:
- Navigate to Window > General > Test Runner.
- Click the mini drop down menu next to the window close button, and click Enable playmode tests for all assemblies.
- Restart your Unity editor to finalize these changes.
Create the UI
In your application's hierarchy, there are a few essential elements that display chat messages on the screen. The RealtimeChat Scene includes a Main Camera and a Canvas that render all the input fields, buttons, and text objects on the screen.
In order for the input fields to be interactive, an EventSystem object is automatically created and displayed in the Hierarchy. Additionally, there are assets such as a simple PNG background, and a Cube to separate the bottom and top sections of the screen.
If you're starting the project from scratch, you'll need to create a Main Camera, which should have the SendMessage
script attached to it.
Design your user interface however you like. In this example, the loadingCircle
is placed on the top right of the screen, and the input fields at the bottom of the screen with the submit button. The chat messages will appear in the middle of the screen and are removed from the UI once they no longer fit on the screen.
Now that the scene is designed, let's add a script to the Main Camera to develop the application's chat room interface.
Add Project Files
The first step is to require the PubNub API and other UnityEngine libraries, including UnityEngine.ui
. The JSONInformation
class formats input field data to be published via PubNub.
The SendMessage
class contains the application’s chatroom logic. Start by instantiating the public variables and creating a chatMessageQueue
to handle message creation and deletion.
Queues are a powerful data structure in C# that allow objects to be inserted at one end and removed from the other. Queues and stacks are useful when you need temporary storage for information; that is, when you might want to discard an element after retrieving its value.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using PubNubAPI;
using UnityEngine.UI;
public class JSONInformation
{
public string username;
public string text;
}
public class SendMessage : MonoBehaviour {
public static PubNub pubnub;
public Font customFont;
public Button SubmitButton;
public Canvas canvasObject;
public InputField UsernameInput;
public InputField TextInput;
public int indexcounter = 0;
public Text deleteText;
public Text moveTextUpwards;
private Text text;
float paddingX = 0F;
float paddingY = 300F;
float padding = 600F;
float height = 30;
ushort maxMessagesToDisplay = 15;
// The Channel to use
string channel = "chatchannel3";
// Create a chat message queue so we can iterate through all the messages
Queue<GameObject> chatMessageQueue = new Queue<GameObject>();
void Start(){}
void CreateChat(JSONInformation payLoad){}
void SyncChat() {}
void Update () {}
void TaskOnClick(){}
}
Initialize the PubNub Object
The PubNub object allows you to make PubNub API calls, like publish
, subscribe
and more. There are more configuration properties than what you see here, but this is all you need for this Quickstart. Of course, you would use your own publish/subscribe keys below.
It's important to set the uuid
for the client. This is typically received from your server after the client logs in successfully.
Successive App Run Behavior
If you test run the app multiple times within a few minutes, you may not see the presence join event appear because the client's UUID is the same as the previous run and is still considered active from the previous run.
// Use this for initialization
PNConfiguration pnConfiguration = new PNConfiguration();
pnConfiguration.PublishKey = "myPublishKey";
pnConfiguration.SubscribeKey = "mySubscribeKey";
pnConfiguration.LogVerbosity = PNLogVerbosity.BODY;
pnConfiguration.UUID = "ReplaceWithYourClientIdentifier";
pubnub = new PubNub(pnConfiguration);
Proper PubNub Initialization
If your app has several views that require the PubNub object, then you can initialize it in the initial view of your app and pass from one view to another.
Listening for Messages & Events
This SubscribeCallback
code has event handler functions where all published messages and other events are received. For this app, you're only interested in the MessageResult
, Status
and PresenceEventResult
handlers. There are several other handlers you can use for other features of PubNub.
- The
MessageResult
handler receives all messages published to all channels subscribed by this client. When a message is received, you're simply appending the content to the bottom display. - The
PresenceEventResult
handler receives all presence events for the channels subscribed by this client. You'll only see thejoin
event of this client unless you open a second client (in a different browser or incognito window) - The
Status
handler allows you to monitor and manage the connection. You'll see aPNConnectedCategory
event for when the client subscribes to the channel. This event triggers the initialPublish
.
pubnub.SubscribeCallback += SubscribeCallbackHandler;
Receiving Messages
The Message
handler receives all messages published to all channels subscribed by this client. When a message is received, it's added below the existing messages.
//Handler
void SubscribeCallbackHandler(object sender, EventArgs e) {
SubscribeEventEventArgs mea = e as SubscribeEventEventArgs;
if (mea.MessageResult != null) {
// Format data into a readable format
JSONInformation chatmessage = JsonUtility.FromJson<JSONInformation>(message.MessageResult.Payload.ToString());
// Call the function to display the message in plain text
CreateChat(chatmessage);
// When a new chat is created, remove the first chat and transform all the messages on the page up
SyncChat();
}
}
Receiving Status Events
The Status
handler allows you to monitor and manage the connection to the PubNub Platform and channels. When the client subscribes to a channel, a PNConnectedCategory
status event is received, which indicates a successful channel connection. You're using this event to submit an initial entry update (publishing a message to a channel).
//Handler
void SubscribeCallbackHandler(object sender, EventArgs e) {
SubscribeEventEventArgs mea = e as SubscribeEventEventArgs;
if (mea.Status != null) {
switch (mea.Status.Category) {
case PNStatusCategory.PNUnexpectedDisconnectCategory:
case PNStatusCategory.PNTimeoutCategory:
break;
case PNStatusCategory.PNConnectedCategory:
TaskOnClick()
break;
}
}
// Added in the previous steps
if (mea.MessageResult != null) {
// Format data into a readable format
JSONInformation chatmessage = JsonUtility.FromJson<JSONInformation>(message.MessageResult.Payload.ToString());
// Call the function to display the message in plain text
CreateChat(chatmessage);
// When a new chat is created, remove the first chat and transform all the messages on the page up
SyncChat();
}
}
Receiving Presence Events
The PresenceEventResult
handler allows you to monitor when this and other clients join and leave channels. The Subscribe
call includes a WithPresence
parameter that indicates that the client wishes to receive presence events on the subscribed channels. In this app, you'll only receive a join
event. If you were to execute the app using another client (like the PubNub Dev Console), you would see a join
event for that client, too. You would also see leave
events when the other clients unsubscribe from a channel or a timeout
event if they go offline without first unsubscribing.
pubnub.SubscribeCallback += SubscribeCallbackHandler;
//Handler
void SubscribeCallbackHandler(object sender, EventArgs e) {
SubscribeEventEventArgs mea = e as SubscribeEventEventArgs;
if (mea.PresenceEventResult != null) {
Debug.Log("SubscribeCallback in presence" + mea.PresenceEventResult.Channel + mea.PresenceEventResult.Occupancy + mea.PresenceEventResult.Event);
}
// Added in the previous steps
if (mea.Status != null) {
switch (mea.Status.Category) {
case PNStatusCategory.PNUnexpectedDisconnectCategory:
case PNStatusCategory.PNTimeoutCategory:
break;
}
}
// Added in the previous steps
if (mea.MessageResult != null) {
// Format data into a readable format
JSONInformation chatmessage = JsonUtility.FromJson<JSONInformation>(message.MessageResult.Payload.ToString());
// Call the function to display the message in plain text
CreateChat(chatmessage);
// When a new chat is created, remove the first chat and transform all the messages on the page up
SyncChat();
}
}
Subscribing to Channels
The Subscribe()
method opens a connection to PubNub and waits for messages to be Publish
-ed to this channel. You can subscribe to more than one channel at a time but you only need one for this Quickstart. The WithPresence()
method enables presence events to be sent for the channel being subscribed in this call.
// Subscribe to a PubNub channel to receive messages when they're sent on that channel
pubnub.Subscribe()
.Channels(new List<string>() {
channel
})
.WithPresence()
.Execute();
Publishing Messages
The TaskOnClick
method is invoked when you click the Submit button. This method wraps the Publish
API so that you can call it from anywhere in the Activity in a standard way.
The messages that publish to this channel are received by this and other clients subscribed to this channel in the Message
handler. The success of a Publish
is updated in the message UI component with the Timetoken
value.
void TaskOnClick()
{
// When the user clicks the Submit button,
// create a JSON object from input field input
JSONInformation publishMessage = new JSONInformation();
publishMessage.username = string.Concat(UsernameInput.text, ": ");
publishMessage.text = TextInput.text;
string publishMessageToJSON = JsonUtility.ToJson(publishMessage);
// Publish the JSON object to the assigned PubNub Channel
pubnub.Publish()
.Channel("chatchannel3")
.Message(publishMessageToJSON)
.Async((result, status) =>
{
if (status.Error)
{
Debug.Log(status.Error);
Debug.Log(status.ErrorData.Info);
}
else
{
Debug.Log(string.Format("Publish Timetoken: {0}", result.Timetoken));
}
});
TextInput.text = "";
}
Displaying Messages
The CreateChat()
function places the new text objects onto the screen. The payload information from the PubNub subscribe is passed to the function, and is then assigned to the text object’s Text. Additionally, the function adds the message to the queue and increments the index counter.
void CreateChat(JSONInformation payLoad){
// Create a string with the username and text
string currentObject = string.Concat(payLoad.username, payLoad.text);
// Create a new gameobject that will display text of the data sent via PubNub
GameObject chatMessage = new GameObject(currentObject);
chatMessage.transform.SetParent(canvasObject.GetComponent<Canvas>().transform);
chatMessage.transform.localPosition = Vector3.zero;
chatMessage.transform.position = new Vector3(canvasObject.transform.position.x - paddingX, canvasObject.transform.position.y - paddingY + padding - (indexcounter * height), 1F);
chatMessage.AddComponent<Text>().text = currentObject;
// Assign text to the gameobject. Add visual properties to text
var chatText = chatMessage.GetComponent<Text>();
chatText.font = customFont;
chatText.color = UnityEngine.Color.blue;
chatText.fontSize = 25;
// Assign a RectTransform to gameobject to manipulate positioning of chat.
RectTransform rectTransform;
rectTransform = chatText.GetComponent<RectTransform>();
rectTransform.sizeDelta = new Vector2(435, height);
// Assign the gameobject to the queue of chatmessages
chatMessageQueue.Enqueue(chatMessage);
// Keep track of how many objects we have displayed on the screen
indexcounter++;
}
The SyncChat()
function moves all existing messages up on the screen to make room for the new message. Additionally, it deletes the first message on the screen to make room for the new message.
void SyncChat() {
// If more maxMessagesToDisplay objects are on the screen, we need to start removing them
if (indexcounter > maxMessagesToDisplay)
{
// Delete the first gameobject in the queue
GameObject deleteChat = chatMessageQueue.Dequeue();
Destroy(deleteChat);
// Move all existing text gameobjects up the Y axis
int c = 0;
foreach (GameObject moveChat in chatMessageQueue)
{
RectTransform moveText = moveChat.GetComponent<RectTransform>();
moveText.position = new Vector3(canvasObject.transform.position.x - paddingX, canvasObject.transform.position.y - paddingY + padding - (c * height), 1F);
c++;
}
}
}
Next Steps
Now that you have your Unity Web app up and running with PubNub, you can learn more about what else you can do with Channels. To discover what else the Unity SDK offers, go to our SDK Reference docs for Unity.
You might also want to check out our Unity Developer Path for more Unity developer content like use-cases, white papers, and sample apps.