Forum Scripting How-to: Utilizing Player.IO in Unity Javascript

Post your problems and discussions relating to scripting in Unity here.

How-to: Utilizing Player.IO in Unity Javascript

Postby runt_struct » November 2nd, 2012, 11:57 am

I wanted to throw out a quick tutorial on how to get Player.IO working in Unity Javascript because I had a hard time finding the solutions online, specifically in regards to the usage of callbacks. As an aside, using C# is probably going to result in a more capable and elegant solution, but in my case I needed to bring Player.IO into an existing script for API comparison purposes. So if you want or need to use Unity Javascript for your project, I hope this helps!

To access the SDK, you'll need to have the DLL in your project as an asset, and import it with this statement:

Code: Select all
import PlayerIOClient;


Now you're ready to access all of Player.IO's functionality. The syntax for calling the library is the same in both languages. Ex:

Code: Select all
PlayerIOClient.PlayerIO.UnityInit(this);


The big difficulty with Unityscript is calling methods which require callbacks. Most of the pages I saw online suggested using Javascript's "Function" type, but I could never get that to work (though if you have gotten this to work I'd love to hear about it!). Additionally, I don't believe there is any way to code an anonymous inline delegate like you can in C#.
Instead, I found that the best way to create delegates is to go straight to the .Net type and declare them as such:

Code: Select all
var pioConnectSuccessCallback : System.Delegate;
var pioConnectErrorCallback : System.Delegate;


In order to actually populate these with data that points to our callback functions, we need to call System.Delegate.CreateDelegate():

Code: Select all
pioConnectSuccessCallback = System.Delegate.CreateDelegate(typeof(PlayerIOClient.Callback.<PlayerIOClient.Client>), this, "PlayerIOConnectSuccess");

pioConnectErrorCallback = System.Delegate.CreateDelegate(typeof(PlayerIOClient.Callback.<PlayerIOClient.PlayerIOError>), this, "PlayerIOConnectFail");

The first argument is the type of the method which will establish our delegate's signature. Using typeof() was the best way I could find to do this. The second argument is the object the method will be called on. So long as your callbacks are in the same class as your Player.IO calls, "this" should be sufficient. The third argument is the name of the method you want to call. Use the name of your callback function with no parentheses or parameters.

Now you can create the actual callback functions themselves:

Code: Select all
function PlayerIOConnectSuccess(client : Client)
{
   Debug.Log("Successfully connected to Player.IO at " + Time.realtimeSinceStartup);
}

function PlayerIOConnectFail(error : PlayerIOError)
{
   Debug.Log("Error connecting: " + error.ToString());
}


Utilizing these callbacks is as easy as passing the delegates as arguments to the Player.IO methods (note last two arguments):

Code: Select all
PlayerIOClient.PlayerIO.Connect(pioGameId, pioConnectionId, pioUserId, pioAuth, pioPartnerId, pioConnectSuccessCallback, pioConnectErrorCallback);


Good luck and happy coding!
runt_struct
 
Posts: 13
Joined: October 12th, 2012, 7:36 pm

Re: How-to: Utilizing Player.IO in Unity Javascript

Postby Benjaminsen » November 2nd, 2012, 1:03 pm

Great post, changed to sticky!
Benjaminsen
.IO
 
Posts: 1444
Joined: January 12th, 2010, 11:54 am
Location: Denmark

Re: How-to: Utilizing Player.IO in Unity Javascript

Postby dreamora » November 2nd, 2012, 4:57 pm

Nice post :)

a warning to those using UnityScript though: UnityScript does not support multicast delegates, so the counterpart to C#s += / -= does not exist in the language at all.
But you can still handle it internally with own delegates that you store in List.<>s for example to properly forward events to more than 1 receiver.
dreamora
 
Posts: 225
Joined: March 2nd, 2012, 9:58 am

Re: How-to: Utilizing Player.IO in Unity Javascript

Postby kaiserxen » March 6th, 2013, 2:16 am

Hi.

i used your method and i could succesfully connect to player.io but now i have a question how can i create/ load databases from javascript?

i was able to do it in c# but its diferent in js, and as my project is made in js i really dont want to recode all to c#. i preciate much your help. thanks
kaiserxen
 
Posts: 9
Joined: March 5th, 2013, 11:22 pm

Re: How-to: Utilizing Player.IO in Unity Javascript

Postby Benjaminsen » March 6th, 2013, 11:47 am

kaiserxen wrote:Hi.

i used your method and i could succesfully connect to player.io but now i have a question how can i create/ load databases from javascript?

i was able to do it in c# but its diferent in js, and as my project is made in js i really dont want to recode all to c#. i preciate much your help. thanks


Not fully sure actually, ping runt_struct in a private message to drag him back here ;)
Benjaminsen
.IO
 
Posts: 1444
Joined: January 12th, 2010, 11:54 am
Location: Denmark

Re: How-to: Utilizing Player.IO in Unity Javascript

Postby runt_struct » March 6th, 2013, 6:29 pm

The only real difference between doing it in Javascript versus C# is that you can't define your callbacks inline with the rest of your code. I have provided a basic BigDB example below. You can see that defining the callback delegates is a little bit tedious, but it works. Ideally you'd wrap you read and write functionality into their own classes, cleaning up some of those global variables. This also allows for multiple simultaneous calls to the API, which can come in very handy. But for the sake of simplicity, I have left that out of the example. Good luck!

Code: Select all
#pragma strict
#pragma implicit
#pragma downcast

import PlayerIOClient;

// Player.IO login variables
var pioGameId : String = "YourGameName";
var pioConnectionId : String = "public";
var pioUserId : String = "YourUserID";
var pioAuth : String = null;
var pioPartnerId : String = null;

// Client reference
var pioClient : PlayerIOClient.Client;

// BigDB Variables
var pioObject : DatabaseObject;
var tableName : String = "YourTableName";
var key : String = "testKey";

// Callbacks
var pioConnectSuccessCallback : System.Delegate;
var pioConnectErrorCallback : System.Delegate;
var pioReadSuccessCallback : System.Delegate;
var pioReadFailCallback : System.Delegate;
var pioWriteSuccessCallback : System.Delegate;
var pioWriteFailCallback : System.Delegate;

// Our variables
@System.NonSerialized
var pioConnectFinished : boolean = false;
@System.NonSerialized
var pioRequestFinished : boolean = false;


function Start()
{
   // Initialize Player.IO
   PlayerIOClient.PlayerIO.UnityInit(this);
   
   // Establish callbacks
   pioConnectSuccessCallback = System.Delegate.CreateDelegate(typeof(PlayerIOClient.Callback.<PlayerIOClient.Client>), this, "PlayerIOConnectSuccess");
   pioConnectErrorCallback = System.Delegate.CreateDelegate(typeof(PlayerIOClient.Callback.<PlayerIOClient.PlayerIOError>), this, "PlayerIOConnectFail");
   pioReadSuccessCallback = System.Delegate.CreateDelegate(typeof(PlayerIOClient.Callback.<PlayerIOClient.DatabaseObject>), this, "ReadSuccess");
   pioReadFailCallback = System.Delegate.CreateDelegate(typeof(PlayerIOClient.Callback.<PlayerIOClient.PlayerIOError>), this, "ReadFail");
   pioWriteSuccessCallback = System.Delegate.CreateDelegate(typeof(PlayerIOClient.Callback), this, "WriteSuccess");
   pioWriteFailCallback = System.Delegate.CreateDelegate(typeof(PlayerIOClient.Callback.<PlayerIOClient.PlayerIOError>), this, "WriteFail");
   
   // Login to Player.IO
   PlayerIOClient.PlayerIO.Connect(pioGameId, pioConnectionId, pioUserId, pioAuth, pioPartnerId, pioConnectSuccessCallback, pioConnectErrorCallback);
   while (!pioConnectFinished)
      yield;
   
   // BigDB Example - ensure we are connected
   if (pioClient != null)
   {
      // Load or create example object
      pioClient.BigDB.LoadOrCreate(tableName, key, pioReadSuccessCallback, pioReadFailCallback);
      while (!pioRequestFinished)
         yield;
      
      // Make some changes
      var counter : int = pioObject.GetInt("exampleInt", 0) + 1;
      pioObject.Set("exampleInt", counter);
      Debug.Log("exampleInt was incremented to " + counter);
      
      // Write the object
      pioRequestFinished = false;
      pioObject.Save(pioWriteSuccessCallback, pioWriteFailCallback);
      while (!pioRequestFinished)
         yield;
   }
}

function PlayerIOConnectSuccess(client : Client)
{
   Debug.Log("Successfully connected to Player.IO at " + Time.realtimeSinceStartup);
   pioClient = client;
   pioConnectFinished = true;
}

function PlayerIOConnectFail(error : PlayerIOError)
{
   Debug.Log("Error connecting: " + error.ToString());
   pioClient = null;
   pioConnectFinished = true;
}

function ReadSuccess(loadedObject : DatabaseObject)
{
   Debug.Log("Successfully read BigDB object at " + Time.realtimeSinceStartup);
   pioObject = loadedObject;
   pioRequestFinished = true;
}

function ReadFail(error : PlayerIOError)
{
   Debug.Log("BigDB Read Error: " + error.ToString());
   pioRequestFinished = true;
}

function WriteSuccess()
{
   Debug.Log("Successfully wrote BigDB object at " + Time.realtimeSinceStartup);
   pioRequestFinished = true;
}

function WriteFail(error : PlayerIOError)
{
   Debug.Log("BigDB Write Error: " + error.ToString());
   pioRequestFinished = true;
}
runt_struct
 
Posts: 13
Joined: October 12th, 2012, 7:36 pm

Re: How-to: Utilizing Player.IO in Unity Javascript

Postby kaiserxen » March 6th, 2013, 8:02 pm

Thanks a lot runt_struct! thats excatly what i needed.

i have two more questions if you are so kind to help me a bit further..

1) the game im working in is a card game and uses a lot of arrays for managing objects and i need to store the databases as arrays too, ive tried many methods in the documentation but none is working well for me.

ive tried things like this:

Code: Select all
function SaveDeckConnectSuccess(client : Client){
Debug.Log("Successfully connected to SAVE DECK");

for (var sd = 0; sd < 5; sd ++){

var obj : DatabaseObject = new DatabaseObject();
obj.Set("DECK", new DatabaseArray());
obj.Set("card"+sd+"atk", player.DECK[sd].cardAtk);
obj.Set("card"+sd+"def",player.DECK[sd].cardDef);
obj.Set("card"+sd+"lvl",player.DECK[sd].cardLevel);
obj.Set("card"+sd+"exp",player.DECK[sd].cardExp);

client.BigDB.CreateObject("SAVEDDATA", NAME+ " " + "card" + sd,obj, PlayerIOsaveSuccess,PlayerIOConnectFail);


what i need is to save the array like example : NAME (player name) > DECK > card(1)atk = 100.

i also tried a method i found in the documentation that was like :

Code: Select all
car.Set("LatestLapTimes.0.Position", 1);   -->>

obj.Set("card.1.card"+sd+"atk", player.DECK[sd].cardAtk);


where that (1) was supossed to be the value of the for loop "sd" and the position to store. but if i put there sd, +sd or whatever it stores it as sd and not the int in sd.... i hope ive explained it well :roll: any idea?

and 2) have you been able to run playerio.multiplayer with javascript?

thats all pal, thankkyou for your time and your help.
kaiserxen
 
Posts: 9
Joined: March 5th, 2013, 11:22 pm

Re: How-to: Utilizing Player.IO in Unity Javascript

Postby wbsaputra » December 12th, 2023, 11:33 am

How about Pixy.js?
wbsaputra
Paid Member
 
Posts: 150
Joined: June 29th, 2010, 4:38 pm


Return to Scripting