【Unity】WebからJSONデータの取得

2024年9月17日

この技術資料では、Unityで非同期処理を実現するための2つの方法、コルーチンとC#の標準機能であるasync/awaitの使い方について説明します。特に、GitHub PagesでホスティングされたJSONデータを取得し、Unityで処理する具体的な手順を紹介します。


1. GitHub Pagesを使った簡易サーバのセットアップ

まず、GitHub Pagesを使ってJSONデータをホスティングし、Unityでそのデータを取得する手順を説明します。

1.1 手順: GitHub PagesでJSONをホスティング

GitHubリポジトリを作成:

  • GitHubで新しいリポジトリを作成し、リポジトリ名を入力します(例:json-server)。
  • リポジトリは「Public」に設定します。
  • data.jsonという名前のファイルを作成し、次のようなサンプルデータを保存します。
   {
     "Name": "太郎",
     "Age": 30,
     "Location": "北海道"
   }

GitHub Pagesを有効にする:

  • リポジトリの「Settings」→「Pages」で、mainブランチを選択し、GitHub Pagesを有効化します。
  • 公開されたURL(例: https://username.github.io/json-server/)が表示されるので、これをメモしておきます。JSONファイルへのURLは、https://username.github.io/json-server/data.jsonになります。

2. Unityでの非同期処理

Unityでは、外部データの取得などにおいて非同期処理が重要です。Unityには、コルーチンを使った非同期処理と、C#のasync/awaitを使った非同期処理の2つの選択肢があります。


3. コルーチンを使った非同期処理

3.1 コルーチンの概要

コルーチンは、Unity独自の非同期処理手法で、メインスレッドをブロックすることなく、時間のかかる処理をフレーム間で分割実行することができます。特に、ゲーム内でタイマーや逐次処理が必要な場合に便利です。

3.2 サンプルコード: UnityWebRequestを使ったコルーチンによるJSONデータ取得

以下は、GitHub PagesでホスティングされたJSONデータを取得し、Unityのコンソールに表示するサンプルです。

using UnityEngine;
using UnityEngine.Networking;
using System.Text.Json;

public class JsonDataLoader : MonoBehaviour
{
    private string jsonUrl = "https://username.github.io/json-server/data.json";

    void Start()
    {
        StartCoroutine(FetchJsonData());
    }

    IEnumerator FetchJsonData()
    {
        using (UnityWebRequest request = UnityWebRequest.Get(jsonUrl))
        {
            yield return request.SendWebRequest();

            if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
            {
                Debug.LogError("Error: " + request.error);
            }
            else
            {
                string jsonData = request.downloadHandler.text;
                UserData userData = JsonSerializer.Deserialize<UserData>(jsonData);
                Debug.Log($"Name: {userData.Name}");
                Debug.Log($"Age: {userData.Age}");
                Debug.Log($"Location: {userData.Location}");
            }
        }
    }

    [System.Serializable]
    public class UserData
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public string Location { get; set; }
    }
}

4. async/awaitを使った非同期処理

4.1 async/awaitの概要

async/awaitは、C#の標準的な非同期処理方法です。非同期タスクをawaitで一時停止し、処理が完了した後に続行することができます。コードの可読性を高め、例外処理もシンプルに管理できます。

4.2 サンプルコード: UnityWebRequestとasync/awaitによるJSONデータ取得

以下は、同様にGitHub PagesのJSONデータをasync/awaitで取得する例です。

using UnityEngine;
using UnityEngine.Networking;
using System.Text.Json;
using System.Threading.Tasks;

public class JsonDataLoader : MonoBehaviour
{
    private string jsonUrl = "https://username.github.io/json-server/data.json";

    async void Start()
    {
        await FetchJsonDataAsync();
    }

    async Task FetchJsonDataAsync()
    {
        using (UnityWebRequest request = UnityWebRequest.Get(jsonUrl))
        {
            var response = await request.SendWebRequest();

            if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
            {
                Debug.LogError("Error: " + request.error);
            }
            else
            {
                string jsonData = request.downloadHandler.text;
                UserData userData = JsonSerializer.Deserialize<UserData>(jsonData);
                Debug.Log($"Name: {userData.Name}");
                Debug.Log($"Age: {userData.Age}");
                Debug.Log($"Location: {userData.Location}");
            }
        }
    }

    [System.Serializable]
    public class UserData
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public string Location { get; set; }
    }
}

5. コルーチンとasync/awaitの比較

特徴コルーチン (Unity)async/await (C# 標準)
可読性コードが分岐しやすい直線的なコードで可読性が高い
例外処理エラーチェックが手動try-catchを使ってシンプルに管理
Unityとの相性Unityのフレームやゲームオブジェクトとの連携が容易メインスレッドとの連携が必要
用途フレーム単位の処理や進行に関わる処理データベースや外部リソースの取得など

適したケース:

  • コルーチン: ゲーム内での時間経過やフレームに基づく処理に最適。UnityのオブジェクトやAPIと密接に連携できる。
  • async/await: 外部APIとの通信やバックグラウンド処理に最適。例外処理が簡単で、コードの可読性も高い。

6. まとめ

  • GitHub Pagesを使って簡易サーバをセットアップし、UnityでJSONデータを取得する: 無料で外部データをホスティングし、ゲーム内でのデータ取得に利用できます。
  • コルーチン: Unity独自の非同期処理で、ゲーム進行やフレーム単位の処理に最適です。
  • async/await: C#の標準非同期処理を利用し、外部リソースの取得や複雑な非同期処理をシンプルに実装可能です。

それぞれの特性を理解し、プロジェクトに応じて最適な手法を選択してください。

参考:UnityのJSONユーティリティーで置き換えた場合

using UnityEngine;
using UnityEngine.Networking;
using System.Collections;

public class JsonDataLoader : MonoBehaviour
{
    private string jsonUrl = "https://username.github.io/json-server/data.json";

    void Start()
    {
        StartCoroutine(FetchJsonData());
    }

    IEnumerator FetchJsonData()
    {
        using (UnityWebRequest request = UnityWebRequest.Get(jsonUrl))
        {
            yield return request.SendWebRequest();

            if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
            {
                Debug.LogError("Error: " + request.error);
            }
            else
            {
                string jsonData = request.downloadHandler.text;
                UserData userData = JsonUtility.FromJson<UserData>(jsonData);
                Debug.Log($"Name: {userData.Name}");
                Debug.Log($"Age: {userData.Age}");
                Debug.Log($"Location: {userData.Location}");
            }
        }
    }

    [System.Serializable]
    public class UserData
    {
        public string Name;
        public int Age;
        public string Location;
    }
}

Unity

Posted by hidepon