- Cubeがクリックされたことを検知
- HTTPリクエスト(GET)でJSONの取得 👈 今回はここ
- HTTPリクエスト(POST)でJSONの送信
- WebSocketによる通信
前回の続きです。
今回はCubeがクリックされた際に、HTTPリクエスト(GET)でJSONを取得します。
Unityアプリに加え、今回はNode.jsでサーバも作ります。
開発環境
- Unity 2022.3.36f1
- Node.js v22.4.0
Unityの修正
スクリプトの差し替え
Assets/Scripts/GetClient.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Networking; public class GetClient : MonoBehaviour { [SerializeField] private string url = "http://localhost:8000/message"; private class Response { public string message; } public void OnClick() { StartCoroutine(GetRequest(url)); } IEnumerator GetRequest(string url) { using (UnityWebRequest webRequest = UnityWebRequest.Get(url)) { yield return webRequest.SendWebRequest(); if (webRequest.result == UnityWebRequest.Result.Success) { var response = JsonUtility.FromJson<Response>(webRequest.downloadHandler.text); Debug.Log(response.message); } else { Debug.Log(webRequest.error); } } } }
スクリプトを作成し、Cubeにドラッグ&ドロップします。
前回、PointerClickには「ClickTarget > OnClick()」を設定していましたが、「GetClient > OnClick()」に差し替えます。
httpの許可
今回は自分で作ったローカルサーバと通信する前提なので、HTTPリクエストを許可してしまい、HTTPでサーバを立てます。
Edit > Project Settings... > Player > Other Settings > Allow downloads over HTTP* を「Always allowed」にすればOKです。
URLがhttp://localhost:3000でよければ、ここの設定は不必要なのですが、のちに同一ネットワークの別PCからIPアドレスを指定して叩くことを考慮し、今のうちに設定しておきましょう。
サーバの作成
package.json
{ "name": "unity-network", "version": "1.0.0", "main": "app.mjs", "scripts": { "start": "node app.mjs" }, "dependencies": { "express": "^4.19.2" } }
app.mjs
import express from 'express'; import { createServer } from 'node:http'; const __dirname = import.meta.dirname; // 後述 const app = express(); const http = createServer(app); app.use(express.json()); app.get('/message', (req, res) => { res.send({ message: 'Ya-Ha-!' }); }); http.listen(8000);
Expressを使って、localhost:8000/messageにアクセスがあった際に、
{ message: 'Ya-Ha-!' }
を返すだけのサーバを作り、
npm start
で起動します。
これで準備OKです。
挙動確認
Unityを実行し、Cubeをクリックするとログに「Ya-Ha-!」と表示されることが確認できます。
解説
__dirnameの取得
今回は、__dirnameを、
const __dirname = import.meta.dirname;
と取得するために、Node.js v22.4.0を使いました。
執筆時のLTSはv20.15.1なのですが、v20.15.1だとこの記法は使えません。
どうやら、v21.2.0から使えるようになったようです。
v21.1.0以前で__dirnameを取得する場合は、
import path from 'node:path'; import url from 'node:url'; const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
これでOKです。
もしくは、.mjsをやめて、.jsにしてしまうのが手取り早いかもしれません。
JSONのパース
Assets/Scripts/ClickTarget.cs(抜粋)
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Networking; public class GetClient : MonoBehaviour { private class Response // JSONをクラス化しておく { public string message; } IEnumerator GetRequest(string url) { using (UnityWebRequest webRequest = UnityWebRequest.Get(url)) { yield return webRequest.SendWebRequest(); if (webRequest.result == UnityWebRequest.Result.Success) { var response = JsonUtility.FromJson<Response>(webRequest.downloadHandler.text); // JsonUtilityを使ってJSONをパース Debug.Log(response.message); } else { Debug.Log(webRequest.error); } } } }
昔は、MiniJSONを使っていた気がするんですが、JsonUtilityというクラスを発見したので、使ってみました。
今回は以上です。
次回はCubeをクリックした際に、HTTPリクエストでJSONをPOSTします。