Real-Time Gaming Blog

Real-time Data Synchronization with Unity and PubNub

6 min read Jordan Schuetz on May 15, 2018
Try PubNub Today

Free up to 1MM monthly messages. No credit card required.

Subscribe to our newsletter

By submitting this form, you are agreeing to our Terms and Conditions and Privacy Policy.

With that, we want to showcase the Unity SDK with PubNub. Data synchronization, which ensures that two or more clients are synced, is essential for multiplayer games specifically.

Some developers avoid real-time development in Unity due to the complexity, however, with the PubNub Unity SDK, multiplayer development is seamless and easy. PubNub is a globally distributed network with APIs for building real-time applications and multiplayer games. PubNub APIs are easy to use so you can iterate fast and get your game published faster than the competition. Additionally, PubNub powers the backend for you, allowing you to focus on innovating your application instead of building a complicated global network.

With that, we want to showcase the Unity SDK with PubNub. Data synchronization, which ensures that two or more clients are synced, is essential for multiplayer games specifically. I built a simple image switcher app that allows one user to take an action, and that action is synced across all other connected clients.

Setting Up Unity

To start, check out my GitHub and clone/download the repo. The repo contains an Assets folder which contains all of the Project Files. Open up Unity, and go to File -> Open Project and select the folder. It will take some time to load the project in Unity. When it completes, open up the Assets folder in your Project tab, and double-click on the SplashScreen Unity Scene.

When you click on the SplashScreen scene, you should see:


To try out the demo, click the Play button at the top.

If you get the following error, follow the steps below:

Scene ‘MainScene’ couldn’t be loaded because it has not been added to the build settings or the AssetBundle has not been loaded.

To fix this, go to File -> Build Settings. Click the Add Open Scenes button. Then go back to your Project tab, and double-click on the MainScene, go back to your Build Settings, and click Add Open Scenes once again. Then in your Project Tab, double-click on the SplashScreen scene again and run the project.

Note: running the MainScene alone will result in an error since it requires UUID information from the SplashScreen. Make sure to always run SplashScreen first.

Running the Project

Now that your project is all set up, click the Run button, enter your username, and you should see the below screen upon submitting.


When you click one of the Picture buttons, you will notice that the cube texture changes. The texture changes only when the client receives a PubNub publish message which means you need an internet connection for the demo to work.

The UUID text at the bottom of the screen is your unique ID that PubNub uses to identify your user. In a real use case, you would want the UUID to be randomly generated and not shown to the end user. However, for the sake of this demo, your UUID is what you entered on the SplashScreen.


To check out the real-time functionality of the application, go to File -> Build Settings, and select the platform you want to build for. I recommend standalone, or WebGL. For WebGL, you will have to run a python server by typing (Mac instructions):

python -m SimpleHTTPServer 8000

Then navigate to your index.html file when you type in http://localhost:8000/ in your web browser.

When you run the windows side by side, you can see that each of the UUID’s are different, however, each screen shows who changed the cube texture last. This is PubNub in it’s simplest form. Try it out for yourself to see how real-time PubNub really is!

PubNub-GitHub-Demo-Screenshot button-red2

Open up two separate windows for the demo

How Does it Work?

SplashScreen Scene

In the SplashScreen scene, I created the script called InputScript which is attached to the GameObject InputObject.  This script takes the string entered in a textbox, and saves it as a public variable so other scenes can access it.

The MainScene has to be able to read the information that was input in the field which is why we created a DontDestroyOnLoad object. DontDestroyOnLoad stays alive even if the scene is changed or deleted.

As you can see in the inspector images below, the string in the Input Script called UUIDinput is blank, however upon submitting the form and changing scenes, the UUIDinput string is now “Jordan“.

Inspector-Screenshot1 Inspector-Screenshot2 Inspector-Screenshot3
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class InputScript : MonoBehaviour
  public InputField Field;
  private bool wasFocused;
  public string UUIDinput;
  public GameObject InputObject;
  void Start(){
  private void Update()
    if (wasFocused && Input.GetKeyDown(KeyCode.Return)) {
    wasFocused = Field.isFocused;
  private void Submit(string text)
    Debug.Log("Submit=" + text);
    UUIDinput = text;

The code above is the Input Script, and listens to every frame for an input event from the keyboard. When it receives a Return response, it runs the Submit function which assigns the UUIDinput string to whatever text was input.  It then changes scenes to the MainScene.


The MainScene consists of three Canvas buttons, a rotating cube, and some text objects.

The below code assigns each button to a variable and then associates each button with the canvas GameObjects. The function TaskOnClick is called when the listener detects a click. We then pass an int as a message through PubNub. The message is then sent to the PubNub servers which distributes the message to anyone currently subscribed to “my_channel“.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using PubNubAPI;
public class mouseButton : MonoBehaviour {
  // Use this for initisoualization
  public Button Button1;
  public Button Button2;
  public Button Button3;
  void Start () {
    Button btn1 = Button1.GetComponent<Button>();
    Button btn2 = Button2.GetComponent<Button>();
    Button btn3 = Button3.GetComponent<Button>();
  void TaskOnClick(int btnnumber){
    if (btnnumber == 1) {
      Debug.Log ("Pressed Button 1");
    }else if (btnnumber == 2) {
      Debug.Log ("Pressed Button 2");
    PublicPubNub.pubnub.Publish ()
      .Channel ("my_channel")
      .Async((result, status) => {
        if (!status.Error) {
          Debug.Log(string.Format("Publish Timetoken: {0}", result.Timetoken));
        } else {

Now that we have code that publishes messages to a channel, let’s write code that allows clients to subscribe to the data stream.

Below we initiate PubNub and assign the UUID to be the inputResponse (which finds the DontDestroyOnLoad gameObject and grabs the UUIDinput string).

Near the bottom of the code, we call pubnub.Subscribe () which subscribes the client to the channel “my_channel“. In the Update() function we rotate the cube based on the delta time.

The pubnub.SusbcribeCallback is the function where you receive any inbound messages that are being published on “my_channel“. In the callback, we have some if statements to see what int‘s we are receiving, and then we changed the cube’s material based on that data.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using PubNubAPI;
using UnityEngine.UI;
public class PublicPubNub : MonoBehaviour {
  public static PubNub pubnub;
  public GameObject CubeObject;
  public Material Meme1;
  public Material Meme2;
  public Material Meme3;
  public float speed = 10f;
  public Text UUIDText;
  public Text lastClickText;
  public string inputResponse;
  // Use this for initialization
  void Start () {
    // Use this for initialization
    PNConfiguration pnConfiguration = new PNConfiguration ();
    pnConfiguration.PublishKey = "pub-c-efb4a8fe-605a-42e8-866a-facc7271a49d";
    pnConfiguration.SubscribeKey = "sub-c-1bb9d4ac-52f4-11e8-85c6-a6b0a876dba1";
    pnConfiguration.LogVerbosity = PNLogVerbosity.BODY;
    inputResponse= GameObject.Find("InputObject").GetComponent<InputScript>().UUIDinput.ToString();
    Debug.Log (inputResponse);
    pnConfiguration.UUID = inputResponse;
    pubnub = new PubNub(pnConfiguration);
    Debug.Log (pnConfiguration.UUID);
    UUIDText.text = "UUID: " + pnConfiguration.UUID;
    pubnub.SusbcribeCallback += (sender, e) => { 
      SusbcribeEventEventArgs mea = e as SusbcribeEventEventArgs;
      if (mea.MessageResult != null) {
        lastClickText.text = "Last Publish Sent by: " + mea.MessageResult.IssuingClientId.ToString();
        if((int)mea.MessageResult.Payload == 1){
          CubeObject.GetComponent<Renderer>().material = Meme1;
        } else if((int)mea.MessageResult.Payload == 2){
          CubeObject.GetComponent<Renderer>().material = Meme2;
        } else if((int)mea.MessageResult.Payload == 3){
          CubeObject.GetComponent<Renderer>().material = Meme3;
      if (mea.PresenceEventResult != null) {
        Debug.Log("In Example, SusbcribeCallback in presence" + mea.PresenceEventResult.Channel + mea.PresenceEventResult.Occupancy + mea.PresenceEventResult.Event);
    pubnub.Subscribe ()
      .Channels (new List<string> () {
  // Update is called once per frame
  void Update () {
    CubeObject.transform.Rotate(Vector3.up, speed * Time.deltaTime);
    CubeObject.transform.Rotate(0f, 0f, -3f * Time.deltaTime);

Wrapping Up

Setting up PubNub with Unity is straightforward and seamless. To download the Unity SDK, visit our Unity documentation. You can download my demo project on my GitHub here. If you have any questions, reach out to me at

More from PubNub

How to Add a Notification Badge to Icons in React Native
Real-time Chat BlogDec 19, 20226 min read

How to Add a Notification Badge to Icons in React Native

Display real-time notification badges with PubNub and React Native to display important information and bring users back to your...

Michael Carroll

Michael Carroll

Digital Twins and the Future of Real-Time Data
InsightsDec 6, 20224 min read

Digital Twins and the Future of Real-Time Data

The concept of Digital Twins has evolved over the last two decades, however, one thing remains the same: the need for real-time...

Michael Carroll

Michael Carroll

How Many Text Characters Fit in a 32KB PubNub Message?
Real-time Chat BlogNov 24, 20224 min read

How Many Text Characters Fit in a 32KB PubNub Message?

Learn the ins-and-outs of PubNub message size and get a better idea of how many text characters fit in a single message.

Michael Carroll

Michael Carroll