注意
UniRx 周りの理解が甘いので、変なこと書いてるかもです。
https://www.hanachiru-blog.com/entry/2020/02/29/120000
現在この辺りを読みながら勉強中なので、何かわかれば追記、修正します。
やること
https://xxxxx.com/xxxxx
にアクセスすると下記のような Json を返す API を、
{
"items": [
{
"user_name": "post",
"points": {
"of_distance": 5,
"of_coin": 5
},
"total_point": 10,
"timestamp": 1592761117
},
{
"user_name": "post",
"points": {
"of_distance": 5,
"of_coin": 5
},
"total_point": 10,
"timestamp": 1592761117
}
]
}
Unity から呼び出して、 同じ構造を持った Class へ Deserialize, Parse する。
ライブラリのインポート
UniRx
Unity で非同期処理のタイミング調整(?)が行えるライブラリ。
async/await が使えるようになる。
書き方によっては使わなくても良さそう。
導入方法
AssetStore から一式インポート
Newtonsoft.Json
Json の Deserialize, Parse をいい感じにやってくれる。
導入方法
この方法で NuGet を import して、 NuGet の機能で Newtonsoft.Json を取得。
すると、 Assets/Packages/Newtonsoft.Json.12.0.3 が取得できる。
実装
通信を行うクラス
UnityWebRequest を使って json を取得して、JsonConvert.DeserializeObject を使って Deserialize, Parse を行う。
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
using System.Collections.Generic;
using Newtonsoft.Json;
public class HttpSample
{
public string url;
public Scores scores { get; private set; }
public IEnumerator Get(System.IObserver<Scores> observer)
{
UnityWebRequest req = UnityWebRequest.Get(url);
yield return req.SendWebRequest();
if (req.isNetworkError)
{
Debug.Log(req.error);
}
else if (req.isHttpError)
{
Debug.Log(req.error);
}
else
{
// json が返る
string result = req.downloadHandler.text;
// Scores 型に変換
this.scores = JsonConvert.DeserializeObject<Scores>();
observer.OnNext(scores);
observer.OnCompleted();
}
}
// クラスに `[JsonObject("xxxxx")]` ,
// クラスプロパティに `[JsonProperty("xxxxx")]` をつけると、
// json parse 時のフォーマットを変更できる
[JsonObject("scores")]
public class Scores {
[JsonProperty("items")]
public List<Score> items;
[JsonObject("score")]
public class Score
{
[JsonProperty("user_name")]
public string user_name;
[JsonProperty("points")]
public Points points;
[JsonProperty("total_point")]
public int total_point;
[JsonProperty("timestamp")]
public int timestamp;
[JsonObject("points")]
public class Points
{
[JsonProperty("of_distance")]
public int of_distance;
[JsonProperty("of_coin")]
public int of_coin;
}
}
}
}
呼び出すクラス
async/await を使って同期的に結果を取得し、取得したクラスを使っていく。
using UnityEngine;
using UniRx;
public class ScoresController : MonoBehaviour
{
// UniRx を入れると async が書ける
async void Start()
{
HttpSample scoreHttp = new HttpSample("https://xxxxxxxxxxxxxxx.com/api");
// await を使うことで、結果を同期的に扱える。
HttpSample.Scores result = await Observable.FromCoroutine<HttpSample.Scores>(observer => scoreHttp.Get(observer));
Debug.Log(result)
}
}