TECHブログ


Unityで作る3Dウォークスルーのバーチャル展示会

はじめに

前回紹介した全天球パノラマは球体の中心からシーンを見渡すコンテンツでしたので、今回は空間を自由に動き回れるWebGLコンテンツを考えてみます。パブリックドメインの絵画を配置してWebブラウザで閲覧できるバーチャル展示会を、Unityを使用して制作します。

開発環境

  • Unity2019.4.x
  • Visual Studio 2019

事前準備

  • 動作確認用にApache等でローカル環境にWebサーバを立てておくと作業しやすい
  • UnityはWebGL用にビルドできる設定にしておく

Unityでの実装

素材の用意

必要となる素材として、シーン全体の環境に使う背景の3Dモデル(大道具)、額縁などプロップの3Dモデル(小道具)、絵画の画像が考えられます。
今回は、大道具はUnity Assetsの3D Free Modular Kitから、小道具の3DモデルはTurboSquidから探して使用しました。また、絵画の画像素材はパブリックドメインとして世界各地の美術館が公開している画像を使用しています。

ウォークスルーの操作

目線の高さに配置したカメラを、前後左右の移動をキーボード操作で向きはマウスで画面をドラッグ操作によって制御できるようにして、一人称視点で動き回れるような仕組みを作ります。
また、移動して壁を突き抜けてしまわないように3Dモデルとカメラに対して衝突判定の設定をしておきます。

向きが変わると進行方向も変わるため、カメラが上を向いている時に真っすぐ進むと天井にぶつかってしまいます。そこで、垂直方向のカメラ向きを変えたとしても進行方向は変わらず、常に地面に対して平行の状態にします。顔を上や下に向けながら前進するイメージです。
Unityでの実装は、カメラの親オブジェクトを作成して前後左右の移動と水平方向の回転を制御させ、カメラには垂直方向のみの回転を制御できるようにしておきます。階層化することで、垂直方向の向きは進行方向に影響を与えなくなります。

画像の表示

額縁のモデルはインスタンスとして共通のものを使用するため、どの絵画の画像を表示するにしても今回使う縦長サイズの幅に合わせなければなりません。
画像をテクスチャとして適用すると、画像の縦横比とは関係なく額縁のサイズにぴったり合って表示されます。横長の画像を表示したい場合は、縦のサイズを元の縦横比になるように調整してあげます。

左の額縁にぴったり合った状態から、右の縦横比を元の画像に合わせた状態に調整。
※画像内の作品はレンブラント作「エウロペの誘拐」(J・ポール・ゲティ美術館所蔵)

下記スクリプトでは、テクスチャ画像が横長の場合のRawImageサイズを調整しています。
※実際はさらに考慮すべき条件がいくつかありますが、例として一部のみ抜粋

// Canvas Imageのサイズ
Vector2 defaultSizeDelta = rawImage.rectTransform.sizeDelta;
// Canvas Imageの縦横比
float defaultImageRate = rawImage.rectTransform.rect.height / rawImage.rectTransform.rect.width;

// テクスチャの横幅が縦幅よりも大きい場合
if (texture.width > texture.height)
{
    // テクスチャの縦横比
    float targetImageRate = (float)texture.height / texture.width;

    // 縦幅を調整する
    rawImage.rectTransform.sizeDelta = new Vector2(
        defaultSizeDelta.x,
        defaultSizeDelta.y * targetImageRate / defaultImageRate
    );
}else{
    ....
}

Webサイトのリンクを開く

ボタンをクリックすると、パブリックドメインの絵画を公開しているWebサイトを開くという機能を、UnityスクリプトからWebブラウザのJavaScript関数を呼び出すことで実装します。そのための設定を、Unity公式リファレンスの「UnityスクリプトからJavaScript関数を呼び出す」を参考に行ってみます。

JavaScriptプラグインの定義

Assetsフォルダ直下のPluginsフォルダに.jslib形式のファイルを配置します。.jslibファイルには呼び出したいJavaScript関数の以下のような構文で定義します。

mergeInto(LibraryManager.library, {
  OpenToBlankWindow: function (_url) {
    window.open(Pointer_stringify(_url),'_blank')
  },
});
  • UnityのC#スクリプトで呼び出す関数を定義します
  • JavaScriptのwindowインターフェースのopen関数を呼び出して指定のWebサイトを開きます
  • Pointer_stringifyヘルパー関数を使用してJavaScript文字列に変換しています

UnityからJavaScriptプラグインの関数を呼び出す

次に、この.jslibファイルで定義した関数をC#で呼び出します。

using System.Runtime.InteropServices;
// .jslibで定義した関数のインポートを宣言
[DllImport("__Internal")]
private static extern void OpenToBlankWindow(string _url);

public void OnClickedOpenURLButton()
{
  OpenToBlankWindow(url);
}

デモ

以上の内容を踏まえて制作したWebGLコンテンツのデモになります。

動作環境

  • PCブラウザでのみ動作します
  • Google Chrome推奨

リンク

新しいタブで開きます。

WebGLコンテンツデモ

  • 額縁内の絵画をクリックすると詳細がポップアップが表示されます
  • 画像のWebサイトへ移動するボタンをクリックすると、パブリックドメイン画像を提供している各美術館のWebサイトを開きます

<操作方法>

  • マウスの左ボタンをドラッグ:視点操作
  • WASDキー or 十字キー:前後左右の移動

まとめ

3D空間を自由に動き回れるWebGLのコンテンツもUnityを利用することで比較的簡単に作成することができそうです。ただし、今回は無料素材を使用しましたが、実際は3Dモデルの用意が必須となるため工数が高くなると予想されます。また、PCのマシンスペック次第では動作が重くなってしまう可能性もあるため、現状は一般的なPCで動作できることを前提とする制約を受けるなど問題も多くあります。
とはいえ、Webブラウザ上での動作は多くの人に体験してもらうことが容易なうえに、3D空間を自由に移動できれば高い没入感を得られるので興味を示してもらいやすいです。コロナの影響により実際の展示会が制限される状況で、バーチャルな展示会であっても実際の体験に近づいたコンテンツが作れるので、WebGLによる3D空間のウォークスルーのようなコンテンツはこれから発展していきそうです。