LotosLabo

プログラミング技術とか気になった情報を載せていきます

UnityとMySQLの連携

はじめに

外部データベースからUnityにデータを送受信する例を紹介します。
今回はデータベースであるMySQLphpMyAdminを通して、PHPから
C#(Unity)へとつなげていきます。

MySQLApacheは既に設定されているものとして進めていきます。
私は開発環境にXamppを使用しているので、Xamppを例としていきます。

今回、サーバーはローカルのものを使っていきますが、ローカルでも外部サーバー、
レンタルサーバーでもIDやパスワードを変更すれば基本同じです。

開発環境の準備

「開発環境」

Windows8
・Xampp ver 3.2.1
PHP ver 5.6.12
MySQL ver 5.6.26


Xamppの導入にはいくつか設定が必要なところがありますので、簡単にですが、
手順を説明します。


①インストール
https://www.apachefriends.org/jp/download.html


②日本語化(したい人のみ)

TeraPad等でUTF-8Nで保存するとよいです。


③Xamppホームに接続

http://localhost/security/index.php

versionが上がったことによって、securityを通さないと設定ページに飛ばないそうです。


MySQLのrootパスワードを変更、ディレクトリにhtaccessを設定

http://localhost/security/xamppsecurity.php


MySQLの日本語の文字化けを防止


phpMyAdminの環境設定を登録する



データベースの用意

取得するデータを予め用意しておきます。

データの作成にはphpMyAdminで行います。作成方法は紹介しませんので、他サイトを参考にしてください。


今回は「ユーザ情報のテーブル」と「ランキングのテーブル」の2つを作成しておきます。

仮にですが以下のように用意しておきました。


●ユーザ情報

ユーザID ユーザ名 性別 ユーザ作成時刻


<テーブル構成>

カラム 型数 Null AI その他
uid int 11 いいえ はい Primary, Unique
name varchar 255 はい いいえ
sex int 1 はい いいえ
create_time varchar 255 はい いいえ


<サンプルデータ>

uid : 入力せず
name: user1
sex : 1
create_time: 関数(UNIX_TIMESTAMP)

uid : 入力せず
name: user2
sex : 2
create_time: 関数(UNIX_TIMESTAMP)


性別の登録は以下の方法が良いとされていますが、今回は仮でもあり、
UIとして男か女のみ選択できる場合であれば、1か2でいいと思います。

作成時刻にはUNIXTIMEを入れておきます。


[性別情報の登録参考サイト]
ISO - DBテーブルに性別カラムを作るなら、男=1, 女=2が標準 - Qiita


●ランキング情報

ユーザID カテゴリ 得点 登録時刻


<テーブル構成>

カラム 型数 Null AI その他
uid int 11 いいえ いいえ
category int 2 はい いいえ
point int 11 はい いいえ
create_time varchar 255 はい いいえ


<サンプルデータ>

uid : 1
category: 1
point : 2500
create_time: 関数(UNIX_TIMESTAMP)

uid : 2
category: 2
point : 500
create_time: 関数(UNIX_TIMESTAMP)

phpからMySQLの接続

MySQLへの接続を行います。
接続を行う際に以下の情報が必要となるので準備が必要です。

MySQL接続ドメイン
MySQLユーザID
MySQLユーザPW

ドメイン名についてはローカルでおこなうので、「localhost:3306」で接続します。

接続するためのPHPファイルを作成します。


MySQLへの接続ですが、以前まではmysql_connectで接続できていたのですが、PHP 5.5.0から非推奨となり、使用できなくなりました。
mysql_connectを使うと、「それは古いからmysqliかPDOを使って」と言われてしまいます。
今回はmysqli形式で書いたものを紹介します。


mysql_connect.php

<?php

// MySQLに接続(ドメイン名、ユーザID、パスワード、データベース名).
$mysqli = @new mysqli( 'localhost:3306','ユーザID','パスワード', 'データベース名' );
if($mysqli->connect_errno) {
  die( 'Connect Error: ' . $mysqli->connect_error() );
}

// データベースのコードを選択.
if(!$mysqli->set_charset( 'utf8' )) {
  die( 'Error loading charaset: ' . $mysqli->connect_error() );
}
?>

このmysql_connect.phpをデータを取得する際に呼び出していきます。


接続テストを行うには、このファイルを
\xampp\security\htdocs\php 等の中にでも入れて、

http://localhost/security/php/mysql_connect.php

で呼び出します。
特にエラーがでなければ成功です。

データを取得する

データベースで登録されてあるデータを取得していきます。
まずPHPからデータを取得していき、Jsonの形で出力し、C#でUnityの画面にDebug.Logで出力します。


・引数なしのデータ取得

PHP側 user_get.php

<?php

// 接続処理.
require_once( dirname(__FILE__). "/mysql_connect.php" );

// 出力形式の設定
header( 'Content-type: application/json; charset=UTF-8' );

$query = "SELECT `uid`, `sex`
          FROM `user_table`";

// クエリ文の実行.
if($result = $mysqli->query( $query )) {

	$user = array();

	// 結果をオブジェク形式で出力.
	while($data = $result->fetch_object()) {
		$user[] = array(
				'uid'=> $data->uid,
				'sex'=> $data->sex,
				);
	}

	// 出力結果が空の時は、nullを出し、JSON形式で変換.
	if(empty($user)) {
		$user = null;
		echo json_encode( $user );
	}else{
		echo json_encode( $user );
	}

	// 結果を解放.
	$result->close();
}

// 接続を切断.
$mysqli->close();
?>

接続テストをしたい場合は、
http://localhost/security/php/user_get.php

にアクセスします。


<Unity側>

今回はJSONObjectを使って取得しますが、UnityではLitJsonを使っても取得できますので、
両方覚えておくと良いです。

JSONObjectを使うには、以下のライブラリをUnityのPluginsディレクトリに入れる必要があります。
http://wiki.unity3d.com/index.php?title=JSONObject#Download

const string LOCALDOMAIN = "ローカルドメイン";
string m_url = "http://" + LOCALDOMAIN + "/security/php/user_get.php";


void Start() {	
 StartCoroutine(GetUser());
}

IEnumerator GetUser() {
 WWW result = new WWW(m_url);
 yield return result;

 if(result.error == null) {
 	JSONObject rdbUserGet = new JSONObject(result.text);
 	for(int i = 0; i < rdbUserGet.Count; ++i) {
 		JSONObject jsonPos = rdbUserGet[i];
 		JSONObject jsonUid = jsonPos.GetField("uid");
 		JSONObject jsonSex = jsonPos.GetField("sex");
 		string uid = jsonUid.int;
 		string sex = jsonSex.int;
 		Debug.Log("ユーザID:" + uid + "性別:" + sex);
 	}
 }
}


[出力結果]
f:id:lo25131:20151017234940j:plain



・引数ありのデータ取得

PHP側 user_get2.php>

引数ありの場合はPHP側では、値を渡してもらうために変数を宣言しておきます。
今回はuidをもらって、そのuidのデータを返してもらうようにします。

●変更点

$uid = $_REQUEST['uid'];

$query = "SELE `name`, `sex`
          FROM `user_table`
          WHERE `uid` = '$uid'";

接続テストをしたい場合は、
http://localhost/security/php/user_get2.php?uid=

にアクセスします。

よくWebのURLみたいに 「?カラム=値」 という形で、
urlの後ろに引数として渡します。 


<Unity側>

Formを作成して、値を送信してからその結果を受取る形になります。

●変更点

WWWForm form = new WWWForm();
form.AddField("uid", uid);
WWW result = new WWW(m_url, form.data);



データを登録する

データベースのテーブルにデータをセットします。


PHP側 ranking_post.php

<?php

// 接続処理.
require_once( dirname(__FILE__). "/mysql_connect.php" );

// 出力形式の設定
header( 'Content-type: application/json; charset=UTF-8' );

$uid = $_REQUEST['uid'];
$category = $_REQUEST['category'];
$point = $_REQUEST['point'];
$createTime = time();

$query = "INSERT INTO `ranking_table`(`uid`, `category`, `point`, `create_time`)	 
          VALUES('$uid', '$category', '$point', '$createTime')";

// クエリ文の実行.
if(!$result = $mysqli->query( $query )) {
	die( 'Error data set: ' . $mysqli->connect_error() );
}

// 接続を切断.
$mysqli->close();
?>


<Unity側>

const string LOCALDOMAIN = "ローカルドメイン";
string m_url = "http://" + LOCALDOMAIN + "/security/php/ranking_post.php";

void Start() {
	StartCoroutine(PostRanking(1, 2, 2555));
}

IEnumerator PostRanking(int uid, int category, int point) {
	WWWForm form = new WWWForm();
	form.AddField("uid", uid);
	form.AddField("category", category);
	form.AddField("point", point);
	WWW result = new WWW(url, form.data);
	yield return result;
	if(result.error == null) {
		Debug.Log("登録完了!");
	}
}

まとめ

Unityでデータを保存する方法はいくつかありますが、今回はMySQLからデータを
送受信する方法を紹介しました。
内部でのデータの保存だと、PlayerPrefs(クラス)、SQLite(データベース)
を使用する方法もあります。
このブログでは紹介しませんが、気になる方はそちらも利用してみると、どん
なときにそのデータの保存方法を使用したらいいか、
使い分けが可能になると思います。