PythonではJSON形式が使いやすくてよく使います。今回UnityでJSONをサーバーにPOST送信する必要があり、躓いた部分を解説していきます。
作業環境:
PC : macOS Sierra バージョン10.12.6
サーバー : Python 2.7.10, Django 1.8.1
クライアント : Unity2017.1.0f3
###JSON作成
まずは送信するJSONのデータを作成します。UnityではJSONをアセット等でも作成できますが標準で使えるJsonUtilityが便利なので使います。JsonUtility.ToJsonはクラスのオブジェクトを入れればstring型でJSONを返してくれます。
[System.Serializable]
public class MyName{
public string name;
}
public MyName myObject = new MyName();
myObject.name = "name";
string myjson = JsonUtility.ToJson(myObject);
現在myjsonの中身はこうなっています。
myjson = {"name":"name"}
ここから躓いたポイント
#間違ったやり方
UnityWebRequest request = UnityWebRequest.Post(url, myjson);
yield return request.Send();
基本文字列はこのように送信できるので同じ要領で送信できると思い込んで送ってしまいます。ですがこれで送ってしまうと中身が以下のようになってしまいます。
myjson = %7b%22name%22%3a%22name%22%7d
これだとサーバー側のPythonがJSONを認識出来ません。どうしてこうなってしまうのかというとPOST送信ではデータをURLに含めて送っていて、URLに使えない文字は変換されてしまうからです。JSONでは「{」「"」を必ず使うため文字が変えられてしまいます。
#正しいやり方
string型をbyte型配列に変換して送信します。UnityWebRequest.Post関数の引数はbyte型を受け取れないので以下のようにしてUnityWebRequestのPOSTインスタンスを作成し、UploadHandlerRawでbyte型のデータをuploadHandlerに追加することで送ることが出来ます。
byte[] postData = System.Text.Encoding.UTF8.GetBytes (myjson);
var request = new UnityWebRequest(url, "POST");
request.uploadHandler = (UploadHandler)new UploadHandlerRaw(postData);
request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
request.SetRequestHeader("Content-Type", "application/json");
yield return request.Send();