unity3d开发时,用PHP作为后台是个不错的选择。对一些数据吞吐量不是很大的游戏,比如某个游戏的排名,登录等等,一般的php程序能够胜任了,并且php语言简单,开发容易对数据库尤其是mysql的支持良好,我们还可以通过php对接一些SDK(比如推送)作为unity3d的中转站。基于以上原因我们完全有理由使用php作为游戏后台。而对于数据吞吐量适中的游戏我们还可以,使用php编写websocket进行更实时的交互通讯(这里我们讨论websocket的情况,有空我再另写一遍来讨论).下面我们来看看unity3d和php的简单交互。
- unity3d通过get方式请求php.
get方式请求php比较简单,就是在url里面加上要传递的参数就可以了。客户端代码:
using UnityEngine; using System.Collections; public class phpUnity2 : MonoBehaviour { private string url = "http://localhost:8081/phptest/phpunity2.php?id=1100001&cid=1200001"; //带get参数id和cid的url void OnGUI() { if (GUILayout.Button("get php")) { StartCoroutine(OnGet()); } } IEnumerator OnGet() { WWW www = new WWW(url); yield return www; if (www.error != null) { print("php请求错误: 代码为" + www.error); } else { print("php请求成功" + www.text); } } }
新建一个c# script贴上以上代码,并把它附加到Main Camera中。
php代码:
<?php /**************************************************************************** * 作者: * 日期: 2016-09-12 * 版本: v1.0 * 说明: 测试 ****************************************************************************/ include_once "dbconfig.php"; if(isset($_GET["id"]) && isset($_GET["cid"])) { echo "get请求成功,id值为:".$_GET["id"].",cid值为:".$_GET["cid"]; } ?>
新建一个php文件贴上以上代码,运行unity3d将会看到以下结果。
- unity3d通过post方式请求php.
unity3d post方式请求php我们要通过WWWForm类来构造一个表单字段。
客户端代码
using UnityEngine; using System.Collections; public class phpUnity1 : MonoBehaviour { private string url = "http://localhost:8081/phptest/phpunity1.php"; // void OnGUI() { if (GUILayout.Button("Post php")) { StartCoroutine(OnGet()); } } IEnumerator OnGet() { //表单 WWWForm form = new WWWForm(); form.AddField("id", 1100001); form.AddField("cid", 1100001); WWW www = new WWW(url, form); yield return www; if (www.error != null) { print("php请求错误: 代码为" + www.error); } else { print("php请求成功" + www.text); } } }
php代码
<?php /**************************************************************************** * 作者: * 日期: 2016-09-12 * 版本: v1.0 * 说明: 测试 ****************************************************************************/ include_once "dbconfig.php"; if(isset($_POST["id"]) && isset($_POST["cid"])) { echo "post请求成功,id值为:".$_POST["id"].",cid值为:".$_POST["cid"]; } ?>
运行unity3d可以看到以下结果.
- unity3d和php后台通讯实例
通过上面的讨论我们了解了unity3d和php的简单交互了,现在我们来实现一个unity3d登录的例子.
我们先用ugui简单的做一个登录界面,
这里我们为了以后使用方便封装了一个Extension扩展类和Common公共类
Common.cs:
using UnityEngine; using System.Collections; using System.Security.Cryptography; using System; namespace Commons { /// <summary> /// 扩展类 /// </summary> public static class Extension { /// <summary> /// 判断字符是否为空 /// </summary> /// <param name="str"></param> /// <returns></returns> public static bool isEmpty(this string str) { if(str.Equals("")) { return true; } else { return false; } } } public class Common { /// <summary> /// 对字符进行MD5加密 /// </summary> /// <param name="str"></param> /// <returns></returns> public static string StrEncrypMd5(string str) { if (str == null) { return "加密字符不能为空"; } MD5 md5 = new MD5CryptoServiceProvider(); byte[] bytRes = System.Text.Encoding.Default.GetBytes(str); ; byte[] targetData = md5.ComputeHash(bytRes); string byte2String = BitConverter.ToString(targetData).Replace("-", ""); ; return byte2String.ToLower(); } } }
客户端代码:
using UnityEngine; using UnityEngine.UI; using System.Collections; using Commons; public class login : MonoBehaviour { public InputField userIdField; public InputField passwordField; public Text statusText; private string userId = ""; private string password = ""; private string url = "http://localhost:8081/phptest/login.php"; void OnLogin() { userId = userIdField.text; password = passwordField.text; if (userId.isEmpty() || password.isEmpty()) { print("账户和密码不能为空"); return; } StartCoroutine(logining()); } private IEnumerator logining() { WWWForm form = new WWWForm(); form.AddField("userId", userId); form.AddField("password", Common.StrEncrypMd5(Common.StrEncrypMd5(password))); //双重加密,由于md5的 WWW www = new WWW(url, form); yield return www; if (www.error != null) { print("error is login:" + www.error); statusText.text = www.error + "..."; } else { print(www.text); statusText.text = www.text; } } }
在MySQL建一个测试的数据表:
DROP TABLE IF EXISTS `tb1`; CREATE TABLE `tb1` ( `userid` varchar(30) NOT NULL, `password` varchar(50) NOT NULL, PRIMARY KEY (`userid`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; -- ---------------------------- -- Records of tb1 -- ---------------------------- INSERT INTO `tb1` VALUES ('100001', '123456'); INSERT INTO `tb1` VALUES ('100002', '123456'); INSERT INTO `tb1` VALUES ('100003', '123456'); INSERT INTO `tb1` VALUES ('100004', '123456');
PHP端代码:
为了操作方便我封装了一个common.php文件和一个dbconfig数据库操作类
common.php<?php /**************************************************************************** * 作者: * 日期: 2016-09-12 * 版本: v1.0 * 说明: 公共函数 ****************************************************************************/ define("DEBUG", "FALSE"); header("Content-Type: text/html;charset=utf-8"); /* * 说明: 调式函数 */ function debug_trace($_msg) { if(defined("DEBUG")) { if(DEBUG == "TRUE") { echo($_msg); } } } ?>
dbconfig.php
<?php /**************************************************************************** * 作者: * 日期: 2016-09-12 * 版本: v1.0 * 说明: 对数据库的封装 ****************************************************************************/ include_once("common.php"); class dbconfig{ //构造函数 function __construct() { if(!$this->mysqli = mysqli_connect($this->host, $this->user, $this->pwd)) { die("Cant connect into database"); } else { debug_trace("连接数据库成功...<br />"); } $this->select_db($this->db_name); } //析构函数 function __destruct() { mysqli_close($this->mysqli); } /* * 说明: */ public function get_mysql_handle() { return $this->mysqli; } /* * 说明: */ public function select_db($_db) { if($this->mysqli != null) { if(mysqli_select_db($this->mysqli, $_db)) { debug_trace("选择数据库成功...<br />"); } else { die("Cant connect into database"); } } } /* * 说明: 执行一个sql无返回值 */ public function execute($_sql) { if(empty($_sql)) { echo "参数不能为空"; return; } if(!mysqli_query($this->mysqli, $_sql)) { debug_trace("执行失败...<br />"); } } /* * 说明: 执行一个查询语句,并执行回调函数 */ public function do_query($_sql, $query_callback = "") { if(empty($_sql)) { debug_trace("参数不能为空"); return; } if($result = mysqli_query($this->mysqli, $_sql)) { $num_rows = $result->num_rows; if($num_rows > 0) { while($row = $result->fetch_assoc()) { if(!empty($query_callback)) { call_user_func( $query_callback , $row ); } } return $num_rows; } else { return 0; } mysqli_free_result($result); } else { debug_trace("执行失败...<br />"); } } //成员变量 private $host = "localhost"; //数据库地址 private $user = "root"; //用户名 private $pwd = ""; //用户密码 private $db_name = "test"; //数据库 private $mysqli = null; } ?>
登录的后台login.php:
<?php /**************************************************************************** * 作者: * 日期: 2016-09-12 * 版本: v1.0 * 说明: 测试 ****************************************************************************/ include_once "dbconfig.php"; $dbcfg = new dbconfig(); $password_md5 = ""; if(isset($_POST["userId"]) && isset($_POST["password"])) { $password = $_POST["password"]; $sql = "select * from tb1 where code='".$_POST['userId']."'"; if($dbcfg->do_query($sql, "login_callback") > 0) { if(md5(md5($password_md5)) == $password) { echo "登录成功..."; } else { echo "登录失败1..."; } } else { echo "登录失败2..."; } } function login_callback($row) { global $password_md5; $password_md5 = $row["name"]; } ?>
运行unity3d可以看到以下结果:
好了对于unity3d和php的简单交互我们就谈论到这里,在实际的开发中我们可能通过xml,json向php发送数,我会另外写一遍来讨论。写的不好,请大家多多指正。