成果物
PCブラウザで実行してる動画
Unityでストリートビューっぽいもの作ってみた#unity #firebase #webgl pic.twitter.com/LV3bBpHEqV
— ユキネコのヤマト (@yamatohkd) October 11, 2020
この記事の趣旨
- Unityで簡単にWebGLアプリをビルドできる
- Firebase Hostingで簡単にWebGLアプリを公開できる
- しかも無料(※制限あり)
WebGLって何??
ブラウザ上で2Dとか3Dをグリグリいじれるスゴイやつ
JavaScriptライブラリだとthree.jsなどが有名
↓サンプル見るだけで楽しい
https://threejs.org/
Unityの3DプロジェクトなんかもWebGL(HTML5 + JavaScript)でビルドできる
※ただしモバイル端末は未サポートなので注意(サポートしてないだけで割と動く)
Unity WebGL コンテンツは現在モバイル端末ではサポートされていないことに注意してください一部の機器、特にハイエンドなものでは動く場合もありますが、現在の大抵の端末は性能不足で Unity WebGL を十分に動かすだけのメモリがありません
UnityでWebGLを利用できるようにする
Unityインストール時に以下の項目をチェックする
・WebGL Build Support
既にUnityをインストールしている場合は、以下の手順でモジュールの確認・追加が可能
参考:Unityにモジュールを後から追加する方法
Unityでプロジェクトを作成
3Dプロジェクトで作業を進めます
1. 3Dビューオブジェクトの準備
まずは有志(warapuri氏)が作成した以下ファイルをダウンロードしてください
参考:UnityとOculusで360度パノラマ全天周動画を見る方法【無料編】
①UnityのProjectウィンドウへドラッグ&ドロップでインポート
②それをHierarchyウィンドウへドラッグ&ドロップ
2. 360度写真の準備
以下のサイトなどで360度写真をダウンロードできます
・360cities.net
スマホカメラでも『Googleストリートビュー』アプリなどで撮影することができるようです
今回は購入後一度だけ使用して物置きに放置されたGoPro MAXで撮影しました
3. 画像をオブジェクトにセット
①画像を**「Resources/Images」フォルダへインポート
②オブジェクトに画像をセット
③画像のMax Sizeを変更**(小さいと画像が荒くなる)
HierarchyウィンドウからSphere100を選択し、
④InspectorウィンドウからScaleを全て100に、
⑤ShaderをUnlit/Textureに、
⑥写真が左右反転している場合はTillngのXを-1に変更
⑦Shere100オブジェクトにCanvasをアタッチして、
⑧Projectウィンドウへドラッグ&ドロップでPrefab化
ボタンもいい感じに作ってPrefab化して、
**「JumpButton」**という名前でResources/Prefabsフォルダへ配置
Prefab化したオブジェクトはHierarchyから削除しておく
4. カメラ制御用のスクリプト
以下のサイトから拝借
Unity:マウスドラッグでカメラを回転して視点を操作するスクリプト
マウスホイールでズームイン/ズームアウトできるようUpdate関数に追記
private float scroll;
private float view;
void Update()
{
scroll = Input.GetAxis("Mouse ScrollWheel");
view = mainCamera.fieldOfView - scroll * 50;
mainCamera.fieldOfView = Mathf.Clamp(value: view, min: 30f, max: 90f);
/** 省略 **/
5. 移動時のカメラ演出用スクリプト
移動するときのビヨ~ン感を出したい
以下のサイトを参考にカメラにブラーを追加する
【Unity】【シェーダ】Radial Blur(放射状ブラー)のポストエフェクトを実装する
初期値は以下にしておく
・Sample Count : 16
・Strength : 0
外から変数を変更できるようスクリプトに以下を追記
public void SetStrength(float _strength)
{
this._strength = _strength;
}
}
6. 写真の位置情報を作成
写真のそれぞれのid, xy座標, 移動先のidを設定
これを元に移動ボタンを作成します
これをCSVファイルにしてResourcesディレクトリに配置
CSVに対応したクラスを作成
public class PhotoPosition
{
public int id;
public float x;
public float y;
public int[] jumpTo;
}
CSVをクラスに変換してくれる無料アセットをインポート
・CSV Serialize
7. メインスクリプトの作成
以下のスクリプトを作成し、適当なオブジェクトにアタッチ
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.IO;
public class CreateSphereController : MonoBehaviour
{
// 写真の位置情報リスト
private List<PhotoPosition> photoPositions;
// 写真のオブジェクト一覧
private Object[] images;
// 3Dビューインスタンス一覧
private List<GameObject> spheres;
// 3Dビューのプレハブ
private GameObject spherePrefab;
// 移動ボタンプレハブ
private GameObject buttonPrefab;
// 移動時のカメラのブラースクリプト
private RadialBlur radialBlurScript;
// カメラのブラーの強さ
float blurStrength;
// カメラのブラー処理用フラグ
bool isUpStrength;
bool isDownStrength;
void Start()
{
spheres = new List<GameObject>();
// Resourcesフォルダのposition.csvを取得
TextAsset csvFile = Resources.Load("position") as TextAsset;
photoPositions = new List<PhotoPosition>();
// CSVから写真の位置情報をオブジェクトリストに変換
photoPositions.AddRange(CSVSerializer.Deserialize<PhotoPosition>(csvFile.text));
// id=1の写真を初期値に設定
PhotoPosition photoPosition = photoPositions.Find(n => n.id == 1);
// プレハブ取得
spherePrefab = (GameObject)Resources.Load("Prefabs/Sphere100");
buttonPrefab = (GameObject)Resources.Load("Prefabs/JumpButton");
// Imagesフォルダ配下をすべて取得
images = Resources.LoadAll("Images", typeof(Texture));
// メインカメラのブラースクリプトを取得
GameObject mainCamera = Camera.main.gameObject;
radialBlurScript = mainCamera.GetComponent<RadialBlur>();
// ID=1の写真で3Dビューオブジェクト生成
spheres.Add(CreateNextSphere(1));
}
// 3Dビューオブジェクトを生成
GameObject CreateNextSphere(int nextPositionId)
{
// IDから写真の位置情報を取得
PhotoPosition nextPosition = photoPositions.Find(n => n.id == nextPositionId);
// 3Dビューのインスタンス生成
GameObject nextSphere = Instantiate(spherePrefab, new Vector3(0.0f, 0.0f, 0.0f), Quaternion.identity);
// 3Dビューオブジェクトのマテリアルを取得
Material material = nextSphere.GetComponent<Renderer>().material;
// 写真をテクスチャに設定
material.SetTexture("_MainTex", (Texture)images[nextPosition.id - 1]);
// 移動用ボタンを生成
foreach (int jumpToId in nextPosition.jumpTo)
{
// 移動先の写真情報を取得
PhotoPosition jumpToPosition = photoPositions.Find(n => n.id == jumpToId);
// 移動用ボタンのインスタンスをCanvas配下に生成
GameObject jumpButton = Instantiate(buttonPrefab, new Vector3(0.0f, -3.0f, 0.0f), new Quaternion(0.0f, 0.0f, 0.0f, 0.0f), nextSphere.transform.Find("Canvas"));
// ボタンクリック時のイベントを追加
jumpButton.GetComponent<Button>().onClick.AddListener(() => OnClickButton(jumpToId));
// 次の写真のxyベクトル
Vector2 nextVector = new Vector2(nextPosition.x, nextPosition.y);
// 移動先の写真のxyベクトル
Vector2 jumpToVector = new Vector2(jumpToPosition.x, jumpToPosition.y);
// ベクトルから角度を計算
Vector2 dt = jumpToVector - nextVector;
float radian = Mathf.Atan2(dt.y, dt.x);
float degree = radian * Mathf.Rad2Deg;
// ボタンの向き、位置を設定
jumpButton.transform.Rotate(0.0f, 0.0f, degree);
jumpButton.transform.localPosition = new Vector2(-5 * Mathf.Cos(radian), -5 * Mathf.Sin(radian));
}
// 3Dビューのインスタンスを返す
return nextSphere;
}
// ボタンクリック
void OnClickButton(int id)
{
// 3Dビューインスタンスを追加
spheres.Add(CreateNextSphere(id));
// カメラのブラー処理開始
isUpStrength = true;
}
// Update is called once per frame
void Update()
{
// カメラのブラー処理を強める
if (isUpStrength)
{
ChangeBlurStrength(true);
}
// カメラのブラー処理を弱める
else if (isDownStrength)
{
ChangeBlurStrength(false);
}
}
// カメラのブラー処理
void ChangeBlurStrength(bool isUpFlg)
{
// 強める
if (isUpFlg)
{
blurStrength += 0.05f;
// 一番強まったら
if (blurStrength >= 1)
{
// 強めるの終了
isUpStrength = false;
// 弱めるの開始
isDownStrength = true;
// 古い方の3Dビュー削除
Destroy(spheres[0]);
spheres.RemoveAt(0);
}
// 弱める
} else
{
blurStrength -= 0.05f;
// 弱まりきったら
if(blurStrength <= 0)
{
// 弱めるの終了
isDownStrength = false;
// 誤差が生じるから明示的に0を指定
blurStrength = 0;
}
}
// ブラーの強さ設定
radialBlurScript.SetStrength(blurStrength);
}
}
1. Firebaseでプロジェクト作成
FirebaseにGoogleアカウントでログイン
「プロジェクトを追加」ボタンを選択し、
プロジェクト名などを入力して作成
2. PCにFirebaseをインストール
Firebase CLIをインストール
npm install -g firebase-tools
3. Firebaseプロジェクトの初期化
まずはFirebaseへログイン
$ firebase login
Firebaseプロジェクトの初期化
$ firebase init
以下の選択肢はHostingを指定
? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, then Enter to confi
rm your choices.
( ) Database: Deploy Firebase Realtime Database Rules
( ) Firestore: Deploy rules and create indexes for Firestore
( ) Functions: Configure and deploy Cloud Functions
>(*) Hosting: Configure and deploy Firebase Hosting sites
( ) Storage: Deploy Cloud Storage security rules
( ) Emulators: Set up local emulators for Firebase features
( ) Remote Config: Get, deploy, and rollback configurations for Remote Config
selectオプションは「Use an existing project」を選択
? Please select an option:
> Use an existing project
Create a new project
Add Firebase to an existing Google Cloud Platform project
Don't set up a default project
自分のプロジェクト一覧が表示されるので、先程作成したプロジェクトを選択
あとはエンター連打でOK!
4. WebGLアプリをデプロイ
作成されたpublicフォルダに、ビルドしたWebGLアプリ(以下ファイル)を配置
・index.html
・Build
・TemplateData
Firebaseへデプロイ
$ firebase deploy
5. ブラウザで表示
完了メッセージに表示されたURLへアクセスするだけ
簡単!
まとめ
WebGLアプリのビルドから公開までが簡単にできました。
せっかくUnityでアプリを作れても、AppStoreやGoogle Playに登録するのって結構大変なんですよね。
WebGLビルドを利用すれば、本記事のFirebase Hostingや、unityroomなどのサイトで簡単に公開できるのでオススメです!
ちなみに撮影した写真は、北海道の美幌峠から望む屈斜路湖でした。