Unityを使用した画像データのMySQLへの保存とUnityでの表示
発生している問題・エラーメッセージ
ご覧いただきありがとうございます。
現在Unityを使用して簡単なシューチングゲームを作成しているのですがその機能の一つとしてランキング機能(ユーザー名、スコア、画面のスクリーンショットの表示)を作成しております。
UnityとPHPを使用した画像データ(画面のスクリーンショット)の送受信なのですが方法がわからず困っております。サーバーへの送信部分は一応書いたのですがform.AddBinaryDataのところでNULLが出てしまっています。
文字列や数値は送受信ができているのが確認できております。
受信はJsonを使用しているのですがJsonだとバイナリーは対応していないと出てきたのですが方法はありますでしょうか?
送信部分
using UnityEngine;
using System.Collections;
using System.IO;
public class Score : MonoBehaviour
{
// スコアを表示するGUIText
public GUIText scoreGUIText;
// ハイスコアを表示するGUIText
public GUIText highScoreGUIText;
// スコア
private int score;
// ハイスコア
private int highScore;
// PlayerPrefsで保存するためのキー
private string highScoreKey = "highScore";
string m_url = 該当のURL
string PlayerName;
Texture2D tex;
byte[] pngdata;
bool isCreate = true;
// Use this for initialization
void Start ()
{
Initialize();
}
// Update is called once per frame
void Update ()
{
// スコアがハイスコアより大きければ
if (highScore < score)
{
highScore = score;
}
// スコア・ハイスコアを表示する
scoreGUIText.text = score.ToString();
highScoreGUIText.text = "HighScore : " + highScore.ToString();
}
// ゲーム開始前の状態に戻す
private void Initialize()
{
// スコアを0に戻す
score = 0;
highScore = 0;
// ハイスコアを取得する。保存されてなければ0を取得する。
//highScore = PlayerPrefs.GetInt(highScoreKey, 0);
}
public IEnumerator LoadScreenshot()
{
yield return new WaitForEndOfFrame();
tex = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
tex.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
tex.Apply();
pngdata = tex.EncodeToPNG();
Destroy(tex);
}
// ポイントの追加
public void AddPoint(int point)
{
score = score + point;
}
public void SetName(string name)
{
PlayerName = name;
}
// ハイスコアの保存
public void Save()
{
// ハイスコアを保存する
PlayerPrefs.SetInt(highScoreKey, highScore);
PlayerPrefs.Save();
StartCoroutine("SetScore");
// ゲーム開始前の状態に戻す
Initialize();
}
//サーバーにハイスコアを送信
IEnumerator SetScore()
{
WWWForm form = new WWWForm();
form.AddField("name", PlayerName);
form.AddField("score", score);
form.AddField("frameCount", Time.frameCount.ToString());
form.AddBinaryData("fileUpload", pngdata, "screenShot.png", "image/png");
WWW result = new WWW(m_url, form.data);
yield return result;
if(result.error == null)
{
Debug.Log("登録完了");
}
}
}
php
$name = $_REQUEST['name'];
$score = $_REQUEST['score'];
$screen = $_REQUEST['screen'];
print($screen);
$sql = "INSERT INTO Score(name, score, screen) VALUES('$name', '$score', 'screen')";
$result_flag = mysql_query($sql);
//クエリ文の実行
if(!$result_flag)
{
die('INSERTクエリーが失敗しました。'.mysql_error());
}
受信部分
IEnumerator GetScore()
{
WWW result = new WWW(url);
yield return result;
if (result.error == null)
{
rdbUserGet = new JSONObject(result.text);
for (int ii = 0; ii < rdbUserGet.Count; ii++)
{
JSONObject jsonPos = rdbUserGet[ii];
JSONObject jsonName = jsonPos.GetField("name");
JSONObject jsonScore = jsonPos.GetField("score");
PlayerName = jsonName.str;
Score = jsonScore.str;
if (PlayerName == "" || Score == "")
continue;
top = new GameObject("name_" + ii);
score = new GameObject("score_" + ii);
GUIText Text = top.AddComponent<GUIText>();
GUIText Text2 = score.AddComponent<GUIText>();
Text.fontSize = 20;
Text2.fontSize = 20;
Text.text = Rank + ":" + PlayerName;
Text2.text = Score;
top.transform.position = new Vector3(0.1f, 0.6f + move, 0);
score.transform.position = new Vector3(0.5f, 0.6f + move, 0);
a = top.GetComponent<GUIText>().color;
a.a = 0.0f;
top.GetComponent<GUIText>().color = a;
score.GetComponent<GUIText>().color = a;
move -= 0.05f;
Rank += 1;
Debug.Log("名前:" + PlayerName + "スコア:" + Score);
}
}
else
{
string error = result.error;
Debug.LogError("www Error:" + result.error);
}
}
php
$query = "SELECT name, score FROM Score Order by score desc";
if($result = mysql_query($query))
{
$user = array();
// 結果をオブジェク形式で出力.
while($row = mysql_fetch_assoc($result))
{
//print($row['name']);
//print($row['score']);
//$user[] = array('name'=> $row->name, 'score'=> $row->score);
$user[] = $row;
//var_dump($user);
}
// 出力結果が空の時は、nullを出し、JSON形式で変換.
if(empty($user))
{
$user = null;
echo json_encode( $user );
}
else
{
echo json_encode( $user );
}
// 結果を解放
//$result->close();
}
補足情報(言語/FW/ツール等のバージョンなど)
より詳細な情報
Unity5.4使用
PHP5.3
Json使用
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
0
>form.AddBinaryDataのところでNULLが出てしまっています。
LoadScreenshotが呼び出されていないようですが、別の所で呼んでいるのでしょうか。
この完了をきちんと待ってから送信処理を行う必要があるかと思います。
>Jsonだとバイナリーは対応していない
バイナリデータを文字列化してJSONに入れるか、
スクショだけJSONとは別にDLするかのどちらかになると思います。
(画像のDL・表示処理は遅いので、ユーザビリティー的にも先にスコア等の必須部分を読み込み→必要に応じて後からスクショを読み込み、の方がスマートかと思います)
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.32%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2016/11/28 18:30
LoadScreenshotは別の所で呼び出しております。
自分でもデバッグ機能で追っていきましたら
yield return new WaitForEndOfFrame();
より下が実行されておらず、そのままSetScore()が呼び出されていましたのでそれでNULLのなっているところまでは分かったのですがここからどう修正すればいいのかというところで悩んでおります。
呼び出すタイミングとしてはゲームオーバーになった瞬間に呼び出したいので
Save関数内で呼び出そうと思ったのですがこちらでもNULLが出たので・・・・
情報不足申し訳ありませんでした。
JSONはご回答いただきました先にPHP側で一度文字列に変換→Unity側で再度変換という方法で試してみたいと思います。
2016/11/28 19:43
StartCoroutine("LoadScreenshot");
StartCoroutine("SetScore");
こんな感じにしているのではないでしょうか。
StartCoroutineは呼び出したメソッドの結果を待たずに次に進む為、これだとLoadScreenshotの処理終了前に送信してしまいます。
呼び出し側のメソッドもIEnumeratorにして
yield LoadScreenshot();
とするか、デリゲートを使用することでLoadScreenshotの処理を待つことが出来ます。