【Unity】WebからJSONデータの取得
この技術資料では、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;
}
}
ディスカッション
コメント一覧
まだ、コメントがありません