Top View


Author matsuyama

デジタルツインで個室の利用状況を監視

2023/04/27

実装

Unity と React そして、React Unity WebGL を使っています。

流れとしては以下です。

  1. Unity を WebGL で Build

  2. 成果物 (js, wasm, data) の gzip を解いて、React から読めるところに置く

  3. React Unity WebGL で成果物を読み込んで表示

    • 成果物が結構大きいので読み込みに時間かかります

一度だけなら簡単な手順ではありますが、実際には、Unity で実装 → React で確認を繰り返すので、Build 時間と gzip を解く手間で、結構めんどくさいです (自動化したい)。

Unity の実装

Cube をたくさん並べます。。。
(次は、写真から 3D モデルを作るとかやりたい)。

Unity の実装

Unity のコード

Unity で個室の色を変えるコード例を以下に示します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Satellite : MonoBehaviour
{

    public void ChangeColor(string status)
    {
        Renderer renderer = this.gameObject.GetComponent<Renderer>();
        Material material = renderer.material;

        switch(status)
        {
            case "occupied":
                material.color = Color.red;
                break;

            case "reserved":
                material.color = Color.yellow;
                break;

            case "vacant":
                material.color = Color.green;
                break;

            default:
                material.color = Color.white;
                break;
        }
    }
}

引数 status に応じて material.color を変える ChangeColor という public メソッドを定義しています。

React のコード

React で Unity を表示する、および、定期的に個室の状況を取得して、Unity に反映させるコード例を以下に示します。

import React, { Fragment, useEffect } from "react";
import { Unity, useUnityContext } from "react-unity-webgl";

const TwinApp: React.FC = () => {
  const { unityProvider, isLoaded, sendMessage } = useUnityContext({
    loaderUrl: "unity/satellite.loader.js",
    dataUrl: "unity/satellite.data",
    frameworkUrl: "unity/satellite.framework.js",
    codeUrl: "unity/satellite.wasm",
  });

  function changeSatelliteColor() {
    fetch('satellite.json')
    .then(response => response.json())
    .then(data => {
      data.statuses.forEach(satellite => {
        sendMessage(satellite.name, "ChangeColor", satellite.status);
      });
    })
    .catch(error => {
      // データの取得が失敗した場合の処理
    });
  }
	
  useEffect(() => {
    if (!isLoaded) {
      return;
    }

    changeSatelliteColor();
    const timer = setInterval(() => {
      changeSatelliteColor();
    }, 10000)

    return () => clearInterval(timer);
  }, [isLoaded])

  return (
    <Fragment>
      <Unity unityProvider={unityProvider} style={{ width: 1024, height: 576 }}/>
    </Fragment>
  )
}

会議室の使用状況 json を fetch して、sendMessage で各会議室オブジェクトの ChangeColor メソッドを呼び出す、という処理を定期的に実行しています。

まとめ

  • React Unity WebGL を使えば Unity で作った 3D を React で簡単に表示できるよ!
matsuyama

matsuyama

最近 Unity 触ってます