Note: this is just my way of doing things feel free to adapt and redesign
So i saw a lot of post about how to connect to a server and using an aidl file(whatever that is) but honestly theres no need for anything other unity for connecting to your own server and database
So im making a tutorial to hopefully provide some insight
I will be using PHP for the backend and coding in C# but your welcome to use any language you are comfortable with
okay so what were gonna do first is create an empty gameobject in unity and name is SessionManager
Once we got that done lets go ahead and make a new C# script and name it SessionManager at this point we can go ahead and attach the script to the empty gameobject and go ahead and open up monodevelop
So first were gonna go ahead and set up and instance to our manager and set up some strings
public static SessionManager Instance{set;get;}
public string registerUrl;
public string loginURL;
public string saveURL;
private void Start(){
Instance = this;
}
so now in the editor you can set up the links to your page containing your scripts which we will handle later on
now were gonna make a check to see if the user has been registered
private void Start(){
//set instance to this
Instance = this;
//check if player has a profile if not open registration
if (!PlayerPrefs.HasKey ("RegisteredWithCloud")) {
//if not activate registration screen
RegistrationCourintine();
} else {
//if they are register login
LoginCourintine();
}
}
now lets add one more string to the top of our script
private string Refid;
okay so now lets make a registration i will try to coment it the best i can but you should definitly read up on WWW if your having a hard time understanding
private IEnumerator RegisterUser(){
//get form instance
WWWForm form = new WWWForm ();
//generate a string for user ref id
string refid = Random.value.ToString() + "ff" + "z" + Mathf.Floor(Random.value).ToString() + Mathf.Floor(Random.value).ToString() + Random.value.ToString();
//Post data
form.AddField ("refid", refid);
//upload to server
WWW w = new WWW (registrationURL, form);
//wait for response
yield return w;
//Handle response
if (!string.IsNullOrEmpty (w.error)) {
//something went wrong
Debug.Log (w.error);
} else {
//register succesful
Debug.Log ("registered successfully");
//set refid for easy login
PlayerPrefs.SetString ("refid", refid);
//set user default data
Refid = refid;
//set user data so it doesnt return null
playerController.Instance.xp = 0;
//user is now registered
PlayerPrefs.SetString ("RegisteredWithCloud", "true");
}
}
So a lot going on in that code so you may has noticed that we called this RegisterUser but in our start function were calling RegistrationCourintine(); and LoginCourintine(); this is because you cannot directly call an IEnumerator like a void so you have to create a wrapper function to be able to call it so lets go ahead and create 4 wrappers
public string ReturnRefId(){
return Refid;
}
public void RegistrationCourintine(){
StartCoroutine (RegisterUser ());
}
public void LoginCourintine(){
StartCoroutine (LoginUser ());
}
public void SaveCourintine(int xp){
StartCoroutine (SaveToServer (xp));
}
the main one i wanna discuss here is saving when you are registering and logging in no data is sent to the server the server is creating and returning logic but when you are saving the game then you have to send logic to the server and as said before you cannot call the IEnumerator directly so you must also include your data calls inside the save wrapper as well
So now lets handle logging the user in
Now please bare with me it was like 3AM when i made this script and its a little messy but it works
private IEnumerator LoginUser(){
//get user information
string refid = PlayerPrefs.GetString ("refid");
//new form instance
WWWForm form = new WWWForm ();
//create post data
form.AddField("refid",refid);
//download the data return by server
WWW download = new WWW(loginURL,form);
//wait for download to finish
yield return download;
if (!string.IsNullOrEmpty (download.error)) {
//something went wrong
Debug.Log ("Error downloading " + download.error);
} else {
//parse download.text for data
//turn into an array of strings
string[] data = download.text.Split((' '));
/*now grab the data in format
* refid
* xp
*/
//set username and password
Refid = data[0];
//set xp
int xp;
int.TryParse (data [1], out xp);
playerController.Instance.SetXp (xp);
Debug.Log ("Load Success");
}
}
I guess the key thing i wanna go over here is when downloading data it is returned in plain text because the only access method that you have in WWW is download.text but you can use TryParse to turn plain text into int but you also have to remember your gonna be sending a string of text back to the user not just one piece of data so you have to split the string up into an array so thats what Split does
on to our last piece of code within our SessionManager so weve been playing the game for a bit its not time to save our game
private IEnumerator SaveToServer(int xp){
WWWForm form = new WWWForm ();
form.AddField ("refid", Refid);
form.AddField ("xp", xp);
WWW w = new WWW (saveURL, form);
yield return w;
if (!string.IsNullOrEmpty (w.error)) {
//something went wrong
Debug.Log (w.error);
} else {
Debug.Log ("Save Successful");
}
}
So this script is pretty straight forward so im not gonna go into much detail
now everything would work if we had a backend but before then you should know registering and login will happen when the scene is loaded but saving doesnt have a call so whenever you wanna save the game you need to call this
SessionManager.Instance.SaveCourintine(xp);
remember that the wrapper accepts and argument that is an int and thats how you upload your data to the server
THE SERVER
Alright lets hop straight into it
so im not gonna explain any of the php code just gonna put it here for reference
So were gonna assume we have a table in our database that contains 3 fields
- id
- refid
- xp
So first we need to connect to our database so lets make a script called connect.php and write the following(with your own info of course)
<?
session_start ();
$host = "localhost";
$user = "user";
$pass = "password";
$db = "my_db";
mysql_connect ($host, $user, $pass);
mysql_select_db ($db);
?>
So now lets create our register.php
<?
header('Access-Control-Allow-Origin: *');
require_once ("connect.php");
$refid = $_POST ['refid'];
$sql = "SELECT * FROM gameUsers WHERE refid='$refid'";
$query = mysql($sql);
$row = mysql_fetch_object($query);
$id = $row->id;
if(empty($id)){
$sql3 = "INSERT INTO gameUsers SET refid='$refid'";
$query3 = mysql_query($sql3) or die(mysql_error());
echo "success";
}else{
echo "account already exist with that refid";
}
?>
Now lets make the login.php
<?
header('Access-Control-Allow-Origin: *');
require_once ("connect.php");
$refid = $_POST ['refid'];
$sql = "SELECT * FROM gameUsers WHERE refid='$refid'";
$query = mysql_query ($sql);
$row = mysql_fetch_object ($query);
$refid = $row->refid;
$xp = $row->xp;
echo $refid . " " . $xp;
?>
now its really important that you echo each value back with a space if you remember we use a space in our Split so that we can parse the data
Now last but not least lets save our game with save.php now this one is pretty easy as well
<?
header('Access-Control-Allow-Origin: *');
require_once ("connect.php");
$refid = $_POST ['refid'];
$xp = $_POST ['xp'];
$sql = " UPDATE gameUsers SET xp='$xp' WHERE refid='$refid'";
$query = mysql_query ($sql) or die (mysql_error ());
?>
now everything is set up perfectly just link these pages in your SessionManager object and test it out!
Well i certainly hope that i was clear and helped out some people if you have any questions feel free to shoot me an inbox thank you