И так мы создали базу данных, создали скрипт, который осуществляет соединение с базой и чтение-запись данных. Теперь нам необходимо соединиться из нашей игры с php-скриптом, и получить из него данные, которые он получает с базы данных.
Т.к. данные которые мы будем получать из php-скрита будут в xml виде то первым делом создадим скрипт XmlParser который будет осуществлять чтение xml-данных, выбор из данных атрибутов name и score, и сохранять значения этих атрибутов в массивы name[] и score[].
using UnityEngine; using System.Collections; using System.Xml; public static class XmlParser { private static XmlDocument doc; private static XmlNode root; private static string[] names; // массив имен private static int[] scores; // массив результатов private static int userLenght; // длинна массива public static void Parse(string xml) { doc = new XmlDocument(); doc.LoadXml(xml); root = doc.LastChild; if (root.HasChildNodes) { userLenght = root.ChildNodes.Count; names = new string[userLenght]; scores = new int[userLenght]; for (int i = 0; i < userLenght; i++) { XmlAttribute nameAtt = root.ChildNodes[i].Attributes["name"]; XmlAttribute scoreAtt = root.ChildNodes[i].Attributes["score"]; names[i] = (string)nameAtt.Value; scores[i] = ConvertStringToInt((string)scoreAtt.Value); } } } private static int ConvertStringToInt(string s) { int j; bool result = System.Int32.TryParse(s, out j); if (result = true) { return j; } else { Debug.Log("Error convert string to int"); return 0; } } public static string Name(int index) { return names[index]; } public static int Score(int index) { return scores[index]; } public static int UserLength() { return userLenght; } }
Теперь создадим скрипт ServerHiScore который будет осуществлять доступ к php-скрипту, получение и отправку данных из приложения на сервер.
using UnityEngine; using System.Collections; public class ServerHiScore : MonoBehaviour { //Set the PHP url here public string PHPUrl = "http://yourDomainName.byethost15.com/HiScore.php"; // адрес скрипта //Set the hash key id public string hashKey = "BRIGHTWORLDGAMES"; // ключ для шифрования данных private WWWForm obj_WWW; private bool b_loaded; private delegate void LoadXmlDel(string str); // Use this for initialization void Start () { } // Update is called once per frame void Update () { } //Отправка данных public void SendScore( int score, string name) { WWWForm w_form = new WWWForm(); //Telling PHP that the user is submiting the data w_form.AddField("action", "PostScore"); //Sending hash code key to prevent unwanted user w_form.AddField("hash", MD5.Md5Sum(name + "-" + score.ToString() + "-" + hashKey)); //Encrypt with MD5 //Sending the user score w_form.AddField("score", score); //Sending the user name w_form.AddField("name", name); //Start waiting for the response back from the server StartCoroutine(WaitingForResponse(new WWW(PHPUrl, w_form), null)); } // public IEnumerator WaitingForResponse(WWW www, System.Funccallback) { yield return www; // ожидаем пока получим с сервера данные if (www.error == null) { // Debug.Log("Successful."); } else { // Debug.Log("Failed."); } if (callback != null) { callback(www.text); callback = null; } //Очищаем данные www.Dispose(); } //Получение данных public void GetScores() { b_loaded = false; WWWForm w_form = new WWWForm(); //Telling PHP that the user is loading the data w_form.AddField("action", "GetScore"); //Start waiting for the response back from the server StartCoroutine(WaitingForResponse(new WWW(PHPUrl, w_form), LoadXMLData)); } //Parse the XML data from the server public bool LoadXMLData(string str) { XmlParser.Parse(str); b_loaded = true; return true; } //Getting User length public int GetUserLength() { return XmlParser.UserLength(); } //Getting User Name by index public string GetNameData(int index) { return XmlParser.Name(index); } //Getting User Score by index public int GetScoreData(int index) { return XmlParser.Score(index); } //Loaded XML public bool IsLoaded() { return b_loaded; } }
При передаче данных, мы также передаем ключ в зашифрованном виде, чтобы никакие злоумышленники не могли записать свои данные на сервер, в php-скрипте мы проверяем совпадает ли ключ который храниться на сервере с ключом который мы передали, и записывает данные только если ключи совпадают. При создании аккаунта на byethost у вас автоматически создается домен с названием как выше имя, http://yourDomainName.byethost15.com/, где вместо byethost15 будет ваше название, посмотрите на панели слева в админке. Также вы всегда может создать другой домен, если этот вас не устраивает.
Теперь реализуем метод MD5. Создайте js-скрипт с следующим содержанием:
#pragma strict static function Md5Sum(strToEncrypt: String) { var encoding = System.Text.UTF8Encoding(); var bytes = encoding.GetBytes(strToEncrypt); // encrypt bytes var md5 = System.Security.Cryptography.MD5CryptoServiceProvider(); var hashBytes:byte[] = md5.ComputeHash(bytes); // Convert the encrypted bytes back to a string (base 16) var hashString = ""; for (var i = 0; i < hashBytes.Length; i++) { hashString += System.Convert.ToString(hashBytes[i], 16).PadLeft(2, "0"[0]); } return hashString.PadLeft(32, "0"[0]); }
Т.к. это js-скрипт, а мы используем его в C# скрипте, то обязательно поместите скрипт MD5 в папку Plugins, иначе компилятров Unity3d будет выдавать вам ошибку. На этом вобщем-то всё. Теперь вы можете просто вызывать методы GetScores() и SendScores() скрипта ServerHiScore. Например у меня есть меню, в котором есть кнопка HiScore, при нажатии на которую появляется окно с результатами, тогда получать данные я буду следующим образом:
using UnityEngine; using System.Collections; public class Menu : MonoBehaviour { public GUISkin customSkin; enum Page {MENU, HOWTOPLAY, HISCORE, HISCOREMENU, EMPTY}; private Page page; private Vector2 scrollPosition = Vector2.zero; private int maxUsers = 10; private GameObject cloud; private ServerHiScore objServerHighScore; // объявляем экземпляр класса ServerHiScore void Awake() { } void Start () { Time.timeScale = 1f; objServerHighScore = this.GetComponentЕсли же мне нужно сохранить данные на сервер, то я делаю следующим образом:(); page = Page.MENU; cloud = GameObject.Find("HiScoreCloud"); } void Update () { } void OnGUI() { GUI.skin = customSkin; switch (page) { case Page.MENU: MenuPage(); break; case Page.HISCORE: HiScorePage(); break; case Page.EMPTY: break; }; } private void MenuPage() { GUI.BeginGroup(new Rect(Screen.width / 1.2f - 125, Screen.height / 1.6f - 100, 250, 200)); if (GUI.Button(new Rect(25, 20, 200, 30), "Start Game", GUI.skin.GetStyle("StartButton"))) { Application.LoadLevel("MainScene"); } if (GUI.Button(new Rect(10, 70, 220, 30), "How to Play", GUI.skin.GetStyle("HowToButton"))) { StartCoroutine(ChangePage(Page.HOWTOPLAY)); } if (GUI.Button(new Rect(25, 120, 180, 30), "Hi-Score", GUI.skin.GetStyle("QuitButton"))) { objServerHighScore.GetScores(); // если нажали кнопку Hi-Score вызываем метод для получения данных StartCoroutine(ChangePage(Page.HISCORE)); } GUI.EndGroup(); } private void HiScorePage() { GUI.BeginGroup(new Rect(Screen.width / 2f - 300, Screen.height / 2f - 210, 600, 420)); GUI.Label(new Rect(200, 50, 200, 50), "Top 10", GUI.skin.GetStyle("HiScoreLabelCenter")); if (objServerHighScore.IsLoaded()) // если данные загружены { int numUsers = objServerHighScore.GetUserLength(); if (numUsers > maxUsers) numUsers = maxUsers; scrollPosition = GUI.BeginScrollView(new Rect(100, 110, 400, 180), scrollPosition, new Rect(0, 0, 250, 30 * numUsers)); for (int i = 0; i < numUsers; i++) { GUI.Label(new Rect(0, i * 30, 35, 30), (i + 1).ToString() + ". ", GUI.skin.GetStyle("HiScoreLabel")); GUI.Label(new Rect(35, i * 30, 220, 30), objServerHighScore.GetNameData(i), GUI.skin.GetStyle("HiScoreLabel")); // получаем имя GUI.Label(new Rect(255, i * 30, 145, 30), objServerHighScore.GetScoreData(i).ToString(), GUI.skin.GetStyle("HiScoreLabel")); // получаем очки } GUI.EndScrollView(); } else { GUI.Label(new Rect(200, 200, 200, 30), "LOADING...", GUI.skin.GetStyle("HiScoreLabelCenter")); } if (GUI.Button(new Rect(210, 300, 180, 30), "Back", GUI.skin.GetStyle("ReplayButton"))) { StartCoroutine(ChangePage(Page.HISCOREMENU)); } GUI.EndGroup(); } IEnumerator ChangePage(Page pageNum) { switch (pageNum) { case Page.HOWTOPLAY: page = Page.EMPTY; while ((transform.position - new Vector3(178f, transform.position.y, transform.position.z)).magnitude > 0.5f) { transform.position = Vector3.Lerp(transform.position, new Vector3(178f, transform.position.y, transform.position.z), Time.deltaTime*3.0f); yield return new WaitForSeconds(0.01f); } page = Page.HOWTOPLAY; break; case Page.MENU: page = Page.EMPTY; while ((transform.position - new Vector3(0f, transform.position.y, transform.position.z)).magnitude > 0.5f) { transform.position = Vector3.Lerp(transform.position, new Vector3(0f, transform.position.y, transform.position.z), Time.deltaTime*3.0f); yield return new WaitForSeconds(0.01f); } page = Page.MENU; break; case Page.HISCORE: page = Page.EMPTY; while (cloud.transform.position.y > 0.1f) { cloud.transform.position = Vector3.Lerp(cloud.transform.position, new Vector3(cloud.transform.position.x, 0f, cloud.transform.position.z), Time.deltaTime*3f); yield return new WaitForSeconds(0.01f); } page = Page.HISCORE; break; case Page.HISCOREMENU: page = Page.EMPTY; while (cloud.transform.position.y < 87.9f) { cloud.transform.position = Vector3.Lerp(cloud.transform.position, new Vector3(cloud.transform.position.x, 88f, cloud.transform.position.z), Time.deltaTime * 3.0f); yield return new WaitForSeconds(0.01f); } page = Page.MENU; break; }; } }
private void SubmitDialog() { GUI.BeginGroup(new Rect(Screen.width / 2 - 150, Screen.height / 2 - 140, 300, 280)); GUI.Box(new Rect(0, 0, 300, 280), "", GUI.skin.GetStyle("PauseBox")); GUI.Label(new Rect(25, 10, 250, 50), "Submit Results", GUI.skin.GetStyle("LevelCompleteLabel")); GUI.Label(new Rect(25, 60, 250, 50), "Your score: " + totalScore.ToString(), GUI.skin.GetStyle("LabelMidCenter")); GUI.Label(new Rect(25, 90, 250, 50), "Enter your name:"); userName = GUI.TextField(new Rect(25, 140, 250, 45), userName, 20); if (GUI.Button(new Rect(105, 200, 80, 24), "Submit", GUI.skin.GetStyle("NextLevelButton"))) { submitResult = true; //сохранение результата на сервер objServerHighScore.SendScore(totalScore, userName); dialog = previousDialog; } if (GUI.Button(new Rect(105, 235, 80, 24), "Back", GUI.skin.GetStyle("NextLevelButton"))) { dialog = previousDialog; } GUI.EndGroup(); }
А можно приложить проект юнити рабочий потому что половина скриптов и ошибками как и PHP файл.. наверно сайт подпортил все :(
ОтветитьУдалитья тоже поипался с этим кодом, в итоге придется писать свое...
ОтветитьУдалитьошибки...
зря потраченое время
или удали эту тему или исправь ошибки, заебал
ОтветитьУдалитьЭтот комментарий был удален автором.
ОтветитьУдалитьв этом скрипте ошибка
ОтветитьУдалитьusing UnityEngine;
using System.Collections;
public class ServerHiScore : MonoBehaviour
{
//Set the PHP url here
public string PHPUrl = "http://yourDomainName.byethost15.com/HiScore.php"; // адрес скрипта
//Set the hash key id
public string hashKey = "BRIGHTWORLDGAMES"; // ключ для шифрования данных
private WWWForm obj_WWW;
private bool b_loaded;
private delegate void LoadXmlDel(string str);
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
}
//Отправка данных
public void SendScore( int score, string name)
{
WWWForm w_form = new WWWForm();
//Telling PHP that the user is submiting the data
w_form.AddField("action", "PostScore");
//Sending hash code key to prevent unwanted user
w_form.AddField("hash", MD5.Md5Sum(name + "-" + score.ToString() + "-" + hashKey)); //Encrypt with MD5
//Sending the user score
w_form.AddField("score", score);
//Sending the user name
w_form.AddField("name", name);
//Start waiting for the response back from the server
StartCoroutine(WaitingForResponse(new WWW(PHPUrl, w_form), null));
}
//
public IEnumerator WaitingForResponse(WWW www, System.Func callback)
{
yield return www; // ожидаем пока получим с сервера данные
if (www.error == null)
{
// Debug.Log("Successful.");
}
else
{
// Debug.Log("Failed.");
}
if (callback != null) {
callback(www.text);
callback = null;
}
//Очищаем данные
www.Dispose();
}
//Получение данных
public void GetScores()
{
b_loaded = false;
WWWForm w_form = new WWWForm();
//Telling PHP that the user is loading the data
w_form.AddField("action", "GetScore");
//Start waiting for the response back from the server
StartCoroutine(WaitingForResponse(new WWW(PHPUrl, w_form), LoadXMLData));
}
//Parse the XML data from the server
public bool LoadXMLData(string str)
{
XmlParser.Parse(str);
b_loaded = true;
return true;
}
//Getting User length
public int GetUserLength()
{
return XmlParser.UserLength();
}
//Getting User Name by index
public string GetNameData(int index)
{
return XmlParser.Name(index);
}
//Getting User Score by index
public int GetScoreData(int index)
{
return XmlParser.Score(index);
}
//Loaded XML
public bool IsLoaded()
{
return b_loaded;
}
}
хотя бы рабочие скрипты залили...
ОтветитьУдалитьИсправте ктонить скрипты и на 5 юньку
ОтветитьУдалитьБольшое спасибо за статью!
ОтветитьУдалитьНаконец нашел интересный пример шифрования при передаче данных на сервер.