JSON データ取得について学ぼう

9d2c38e6fe48e61528f6b2d34370768f

この章で学ぶこと

JSON データ取得について学びます。

JSON とは

63ab2988b4cf0591e5dd408ad473bb4e

JSON は JavaScript Object Notation(JSON、ジェイソン)はデータ記述言語の1つです。JSON は JavaScript オブジェクトにとても似ている形式の文字列です。

といっても、みなさんの中には JavaScript を知っているわけではない人も多いと思うので、Unity で使う基本データ型(文字列、数値、配列、論理型やその他のリテラル型)を使うことができて、柔軟にデータを表現することができると覚えておきましょう。

たとえば、このようなデータがあるとします。プロパティ名は Unity でも使われている、オブジェクトのプロパティの名前と同じ役割です。

  • プロパティ名は「number」
    • 値は、整数の 1
  • プロパティ名は「float」
    • 値は、浮動小数点の 23.4
  • プロパティ名は「bool_ok」
    • 値は、真偽値の true
  • プロパティ名は「name」
    • 値は、文字列の MyName

こちらは JSON データでは以下で表現できます。

3484da3d26f272ede691d421f73da1b9

このようなデータです。これから話すために分かりやすく、少し色を付けます。

19cea4e2d46d153eb0f9e423e98b41a5

{
  "number":1,
  "float":23.4,
  "bool_ok":true,
  "name":"MyName"
}

このようなルールでデータが作られています。

30c03f890ae6f717ab9fd2effb89b3e1

Unity で受信したときに扱える JSON は {} で囲われたオブジェクト型ではじまっています。

fae9f572145e6e8efad9b8056551657f

ここでいう "number""float""bool_ok""name" が、値の名前(プロパティ名)です。ダブルクォーテーションで囲んだ名称にします。Unity で読み込まれたとき、変数名として扱われます。

715d8b39d9e5d1ed217095505da4cb91

それぞれの値の名前(プロパティ名)に対応した値は : で区切って設定しています。

666b08142ec856ff892179e2364b35ba

青文字の部分が、各プロパティの実際の値です

以下のような型表現ができます。ひとまず、Unity でも理解しやすい number の整数・浮動小数点, string , 理論値 boolean, 文字列が理解できていれば OK です。

ちょっと array と object は、はじめは難しい。

  • number 型
    • 整数を表現。たとえば、整数の 1 は 1 と記述する。
      • 今回の "number":1
    • 浮動小数点数。たとえば、浮動小数点数の 23.4は 23.4 と記述する。
      • 今回の "float":23.4
    • 10 進法のみですが指数も表現できます。
  • string 型
    • 文字列を表現。たとえば、文字列の MyName は "MyName" と記述する。
      • 今回の "name":"MyName"
  • null 型
    • null を表現。小文字で null と記述する。
  • true 型
    • 理論値 true を表現。小文字で true と記述する。
    • 今回の "bool_ok":true
  • false 型
    • 理論値 false を表現。小文字で false と記述する。
  • array 型
    • JavaScript でいう配列型を表現。値を [] でくくる。たとえば、a と b と c の文字列の入ったの配列は ["a","b","c"] と記述する。
    • Unity C# でいうと List 型に近いものです
  • object 型
    • JavaScript でいうオブジェクト型を表現。値を {} でくくる。プロパティ名はダブルクォーテーションで文字列として記述して、値は前述の各型で記述する。
    • JSON データもオブジェクトではじまっているとも言えます。

6c9cb3ece828fd3ebec43b869a97dbf3

そして、各プロパティはカンマで区切られます。末尾にはカンマは入れません。

✅参考文献

✅補足

  • [] で配列ではじまる JSON も表現できますが Unity で受け取ったときに、ひと手間かかるデータなので、一旦ここでは割愛します。

JSON データに慣れよう

25365ec06cac99fdaecaf0d97df14a34

✅参考文献

こちらの文献でも紹介されている JSON Parser https://jsonparser.org/ というツールで、少し JSON データに慣れてみましょう。

例題 1

{
  "number":1,
  "float":23.4,
  "bool_ok":true,
  "name":"MyName"
}

こちらを左側にコピーペーストして、JSON Parse ボタンをクリックして JSON 構造を体験します。

例題 2

「価格が 500 円」

価格を示すプロパティ名は英語 price に置き換えて表現してみましょう。

📋答え(出題中は開かないでくださいね)
{"price":500}

例題 3

「自分の名前」

名前を示すプロパティ名は英語 name に置き換えて表現してみましょう。

📋答え(出題中は開かないでくださいね)
{"name":"たなかせいご"}

例題 4

「緯度が 35.681236 経度が 139.767125 の場所の名前が東京タワー」

  • 緯度を示すプロパティ名は latitude
  • 経度を示すプロパティ名は longitude
  • 場所を示すプロパティ名は placeName
📋答え(出題中は開かないでくださいね)
{
{
  "latitude":35.681236,
  "longitude":139.767125,
  "placeName":"東京タワー"
}

データ表現例

いくつかのデータ例を元に JSON でのデータ表現を把握します。

JSON データの構造を、人間の生活や IoT のセンサーや住所などを例にして表現してみました。

日時・イベント名

{
  "date": "2023-04-08T07:19:56+09:00",
  "eventName": "バースデーパーティー"
}

たまご・ぶどう・肉などの買い物リスト

{
  "shoppingList": [
    {
      "name": "たまご",
      "quantity": 12
    },
    {
      "name": "ぶどう",
      "quantity": 1,
      "unitPrice": 200,
      "currency": "JPY"
    },
    {
      "name": "肉",
      "quantity": 2,
      "unitPrice": 1000,
      "currency": "JPY"
    }
  ]
}

温度センサーの1回の値(小数点第一位まで)

{
  "temperatureSensorValue": {
    "value": 25.5,
    "unitOfMeasurement": "℃"
  }
}

Windows PC 商品名・メーカー名・型番・価格・消費税

{
  "productDetails": {
    "productName": "Hyper Laptop Z 2930",
    "manufacturerName": "PC Paradise",
    "modelNumber": "HL-Z-2930-BK",
    "priceDetails": {
      "priceAmount": 200000,
      "currencyCode": "JPY",
      "taxDetails": {
        "taxAmount": 20000,
        "taxRatePercentage": 10
      }
    }
  }
}

JSON データの送信や受け取ったデータの JSON 解析は JsonUtility

305255eea1072f3becd161d1df9a5755

JSON データの送信や受け取ったデータの JSON 解析は、Unity でビルドインされている JsonUtility が便利です。

この章では、シンプルな JSON データをサーバーから受け取って、Unity の型で使える流れを学んでみましょう。

Codespace の起動

0a3a35f3418068b7713ddaa729f2c660

GitHub にログインした状態で https://github.com/codespaces にアクセスします。

34de49185c6b28fb938519084d5b36fe

Codespaces のページです。さきほど使っていた Codespace をクリックして起動します。

サーバの起動

0a3a35f3418068b7713ddaa729f2c660

  • ターミナルで node term1-2-chapter03.js をサーバ起動
  • ポートタブで今回のサーバ起動を公開
  • シークレットウィンドウで今回のサーバが公開されているか確認します

こちらの手順を進めます。

✅ポイント

  • 今回は GET リクエストで 1 つの仕組みを作っています
  • /api/get/json というパスで GET リクエストでアクセスすると {"name":"Box1","name2":"Box2"}} という JSON データが取得できます
    • これを Unity 内の name というプロパティで扱ってシーンのテキストに反映します

今回の Unity シーンを起動

6049726527f3133083e8ca07d1e6261c

Project タブから Assets > Scenes を選択します。Scene-Term1-2-Chapter03 をダブルクリックして起動しましょう。

Term1_2_Chapter03_CubeEvent.cs 変更

Assets/Scripts/Term1_2_Chapter03_CubeEvent.cs をエディタで開きます。

using UnityEngine;
using UnityEngine.EventSystems;

using System.Collections;       // IEnumerator のための参照
using UnityEngine.Networking;   // UnityWebRequest のための参照
using System;                   // Serializable のための参照

public class Term1_2_Chapter03_CubeEvent : MonoBehaviour, IPointerClickHandler
{
    // JSON データ化する NameData ベースクラス
    [Serializable]
    public class NameData
    {
        // name というプロパティ名で string 型で変換
        public string name;
        // name2 というプロパティ名で string 型で変換
        public string name2;
    }

    // アクセスする URL
    // サーバーURL + /api/get/json でアクセス
    string urlGitHub = "ここにサーバーURLを入れる";

    public void OnPointerClick(PointerEventData eventData)
    {
        // マウスクリックイベント
        // Debug.Log($"オブジェクト {this.name} がクリックされたよ!");

        // HTTP GET リクエストを非同期処理を待つためコルーチンとして呼び出す
        StartCoroutine("GetGitHubData");
    }

    // GET リクエストする本体
    IEnumerator GetGitHubData()
    {
        // HTTP リクエストする(GET メソッド) UnityWebRequest を呼び出し
        // アクセスする先は変数 urlGitHub で設定
        UnityWebRequest request = UnityWebRequest.Get(urlGitHub);

        // リクエスト開始
        yield return request.SendWebRequest();

        // 結果によって分岐
        switch (request.result)
        {
            case UnityWebRequest.Result.InProgress:
                Debug.Log("リクエスト中");
                break;

            case UnityWebRequest.Result.Success:
                Debug.Log("リクエスト成功");

                // コンソールに表示
                Debug.Log($"responseData: {request.downloadHandler.text}");

                // そのうえで ShibaData クラスで JSON データ化
                NameData nameData = JsonUtility.FromJson<NameData>(request.downloadHandler.text);

                // Title にテキスト割り当て
                GameObject.Find("Title").GetComponent<TextMesh>().text = "Loaded!";

                break;
        }


    }
}

以下を修正します。

// アクセスする URL
// サーバーURL + /api/get/json でアクセス
string urlGitHub = "ここにサーバーURLを入れる";

こちらをサーバー URL に /api/get/json というパスを加えて変更して保存します。

解説していきます。

// JSON データ化する NameData ベースクラス
[Serializable]
public class NameData
{
    // name というプロパティ名で string 型で変換
    public string name;
    // name2 というプロパティ名で string 型で変換
    public string name2;
}

まず、JsonUtility.FromJson が JSON データ化する NameData ベースクラスを用意します。これは、このあと受け取る {"name":"Box1","name2":"Box2"}} に合わせたものです。

using System;                   // Serializable のための参照

また、この対応をするために、こちらの関数群も呼び出しています。

// そのうえで ShibaData クラスで JSON データ化
NameData nameData = JsonUtility.FromJson<NameData>(request.downloadHandler.text);

そのうえで JsonUtility.FromJson 関数で、このように呼び出します。こうすると、ダウンロードしたテキスト request.downloadHandler.text<NameData> のところで、さきほどのクラスをひな形にしながら nameData という変数に代入します。

これ以降は、うまくロードできれば nameData は NameData 型として扱われるので、コードヒントもしっかり出ます。

7841c12d92f8e7c2ffb4b5d743532232

キューブをクリックすると、現在は

// Title にテキスト割り当て
GameObject.Find("Title").GetComponent<TextMesh>().text = "Loaded!";

となるので Loaded! の固定値ですが、

080db25e7155c27f64dccd36dd9d2c31

nameData のあとに . と打ち込んで name を打ち込んでみると、今回のクラスの値が呼び出せます。

// Title にテキスト割り当て
GameObject.Find("Title").GetComponent<TextMesh>().text = nameData.name;

と記述して保存して、

3039cb6387befa4ab05f998ab307caa3

このように Box1 という値を呼び出してみましょう。

まとめ

  • JSON データは、データの構造が作れるので様々なデータがやり取りできるようになります
  • Unity では JsonUtility クラスがあるのでこれを使って JSON をあつかうことができます

今回の Codespace の終了

0a8b4cfb807e57ea1382292a757c6899

今回の Codespace 終了しておきましょう。

results matching ""

    No results matching ""