「Unity」 経営ゲーム開発 Part3
今、
パズドラやサウザンドメモリーズのような
ログイン機能のいらないゲームを考えています。
...ができません。出来ているっぽいです。(2013/12/20追記参照)
(2014/01/26追記)出来ました!!
「ログイン機能のいらない」 というのは、以下の画面遷移のことです。
[初期起動時]
タイトル画面→ユーザー登録画面→メイン画面
[次回起動時]
タイトル画面→メイン画面
こんな風に開発したいんですが、上手くいきません。
Unityで上記を行うなら、
①ユーザー登録画面で、記入したデータをデータベースに挿入する際に、
同時にIDを返して、それを PlayerPrefsで保存する。
②次回起動時に、PlayerPrefs.HasKey でIDを調べて、
IDが保存されてたら、IDに合ったデータをデータベースから呼び出す。
③メイン画面に遷移する
…っていう風にできると思う。
まぁ、そもそも
PHPとUnityとの連携がどうなっているのかが、イマイチよく分からない。
なんかPHPでprintとかechoとかで出力したものを、
Unity側の www で受け取っているのかなぁ…。
ちょっと実験してみた。
以下のスクリプトは、
前の記事(http://shivat.hatenablog.com/entry/2013/12/13/223334)
で書いたPHPを少し改良したものです。
以下の2つの違いは、赤色の部分のみです。
①[ print ありバージョン]
***************************************************************************
//SQL文
$sql = "insert into user_tbl(name, season, wincount, losecount, rank)values(?, ?, ?, ?, ?)";
//文を実行する準備を行い、文オブジェクトを返す
$stmt = $dbh -> prepare($sql);
//SQLを実行する
$stmt -> execute(array($name, $season, $wincount, $losecount, $rank));
// 最後に生成した ID を取得
print $dbh->lastInsertId();
//コミットは最後
$dbh->commit();
//データベースとの接続を切断する
$dbh = null;
***************************************************************************
[①の結果]
②[ print なしバージョン]
***************************************************************************
//SQL文
$sql = "insert into user_tbl(name, season, wincount, losecount, rank)values(?, ?, ?, ?, ?)";
//文を実行する準備を行い、文オブジェクトを返す
$stmt = $dbh -> prepare($sql);
//SQLを実行する
$stmt -> execute(array($name, $season, $wincount, $losecount, $rank));
// 最後に生成した ID を取得
$dbh->lastInsertId();
//コミットは最後
$dbh->commit();
//データベースとの接続を切断する
$dbh = null;
***************************************************************************
[②の結果]
うん。
まず、結果の53という数字は挿入されたユーザーのIDです。
やっぱり、
printやechoで出力されたものがwwwで取れるっぽいです。
んで、
成功した!
…と思って、これを PlayerPrefs.SetInt("id", req.text);
(※ req.text はwwwで取ってきた値です。)
で保存しようとしたら、
以下のようなエラーが出た。
BCE0017: The best overload for the method 'UnityEngine.PlayerPrefs.SetInt(String, int)' is not compatible with the argument list '(String, String)'.
どうやら、wwwで取ってきたものはString型らしい。
じゃあ、
String を Int にしたらいいんじゃないか…と思い、
var id : Int = int.Parse(req.text);
でやってみたところ、以下のエラーが出た。
FormatException: Input string was not in the correct format
System.Int32.Parse (System.String s) ...
FormatExceptionは、数値に変換できない文字列を与えると発生するらしい。
たとえば、「5a」とか「5+5」とかが例にあたる。
ん?こいつなんだ?
じゃあ、
PlayerPrefs.SetString ならどうだろうと思い、再度チャレンジ。
結果なんにもエラーが出なかった…が、
本当に保存されているのかを
Debug.Log(PlayerPrefs.GetString("id"));
で調べてみたところ、以下のようになり表示されませんでした。
しかし、
***************************************************************************
function StartButton(){
if(!PlayerPrefs.HasKey("id")){ //idに何か入っているか調べる
//入ってなかったら,UserCreate画面へ移行
Application.LoadLevel("UserCreate");
}else{
//入ってたら,Main画面へ移行
Application.LoadLevel("Main");
}
}
***************************************************************************
上記のように、PlayerPrefs.HasKey で、
PlayerPrefsの中に値が入っていたら、Main画面、
PlayerPrefsの中に値が入っていなかったら、UserCreate画面へ移行する
スクリプトをやってみると、
Main画面に移行しました。
つまり、Debug.Logでは表示されないような値が入っているようです。
困りました…。
IDに合ったデータをデータベースから呼び出す処理ができないです。
うん。
上手くいかないのは、ここが原因です。(3日間も悩み中)
とにかく、もう少し色々試してみようと思います。
続きまーす。
<追記 2013/12/19>
変数の型を調べる方法を見つけた。
PHPファイルに
var_dump(調べたい変数);
を入れると、型を返してくれるらしい。
var_dump()関数は、変数の情報を出力する機能を持っているとか…。
[実行コマンド]
print $dbh->lastInsertId();
var_dump($dbh->lastInsertId());
[結果]
60string(2) "60"
と出た。
やっぱり、String型らしい。
んで、
lastInsertId()のことをよく調べてみると、
>>データベースに挿入された最後の行の行IDに相当する文字列を返します。
…とのことらしい。
よく調べず、適当に使うものじゃないですね…。
<追記 2013/12/20>
友人に相談したところ、
同じプログラムでやってみてもらったら、
PlayerPrefsに格納されていて、デバッグログに表示されました。
…意味が分かりません。
プログラムが成功していたのは、嬉しいですが、
悩みまくっていた数日間がむなしくなりました。
私のUnityではできなくて、友人のUnityではできるとは…。
バージョンの違いしか考えられないですね。
おかしいな。
最新のバージョンを使用しているはずなのに…。
とにかく、
jsonとか色々入れてしまったのも原因かもしれないですから、
一度整理しなおそうと思います。
<追記 2014/01/26>
諦めかけていたID取得が上手くできました!!
意外と、簡単なコードで出来ました。
以前に、一度試していたはずだったんですが…、
なんでその時できなかったんだろう...
まあ、とりあえず、コードをメモします。
***************************************************************************
//省略します
yield req;
if(req.error != null || req.text == ""){
Debug.Log(req.error);
}else{
Debug.Log(req.text);
for(var i=0;i<req.text.Length;i++){
if(req.text.Substring(i,1)=="0"){id=id+"0";}
if(req.text.Substring(i,1)=="1"){id=id+"1";}
if(req.text.Substring(i,1)=="2"){id=id+"2";}
if(req.text.Substring(i,1)=="3"){id=id+"3";}
if(req.text.Substring(i,1)=="4"){id=id+"4";}
if(req.text.Substring(i,1)=="5"){id=id+"5";}
if(req.text.Substring(i,1)=="6"){id=id+"6";}
if(req.text.Substring(i,1)=="7"){id=id+"7";}
if(req.text.Substring(i,1)=="8"){id=id+"8";}
if(req.text.Substring(i,1)=="9"){id=id+"9";}
}
PlayerPrefs.SetString("id", id);
Debug.Log(PlayerPrefs.GetString("id"));
}
//メモリ解放
req.Dispose();
***************************************************************************
[実行結果画像]
はい。
171回試行錯誤を繰り返して、やっと出来ました。
大変でしたが、達成感で、もうどうでもいいです。
コードはきたないですが、もうどうでもいいです。
1月末までには、Google Playに出そうと思います。
ではでは。