LoginSignup
4
5

More than 3 years have passed since last update.

UnityとFirebaseでストリートビューっぽいの作る

Last updated at Posted at 2020-10-11

成果物

PCブラウザで実行してる動画

iPhoneのSafariから実行

この記事の趣旨

  1. Unityで簡単にWebGLアプリをビルドできる
  2. Firebase Hostingで簡単にWebGLアプリを公開できる
  3. しかも無料(※制限あり)

WebGLって何??

ブラウザ上で2Dとか3Dをグリグリいじれるスゴイやつ

JavaScriptライブラリだとthree.jsなどが有名
↓サンプル見るだけで楽しい
https://threejs.org/

Unityの3DプロジェクトなんかもWebGL(HTML5 + JavaScript)でビルドできる

※ただしモバイル端末は未サポートなので注意(サポートしてないだけで割と動く)

Unity WebGL コンテンツは現在モバイル端末ではサポートされていないことに注意してください一部の機器、特にハイエンドなものでは動く場合もありますが、現在の大抵の端末は性能不足で Unity WebGL を十分に動かすだけのメモリがありません

参考:WebGL のブラウザー間での互換性

UnityでWebGLを利用できるようにする

Unityインストール時に以下の項目をチェックする
・WebGL Build Support

既にUnityをインストールしている場合は、以下の手順でモジュールの確認・追加が可能
参考:Unityにモジュールを後から追加する方法

Unityでプロジェクトを作成

3Dプロジェクトで作業を進めます

1. 3Dビューオブジェクトの準備

まずは有志(warapuri氏)が作成した以下ファイルをダウンロードしてください
* Sphere100.fbx

参考:UnityとOculusで360度パノラマ全天周動画を見る方法【無料編】

①UnityのProjectウィンドウへドラッグ&ドロップでインポート
②それをHierarchyウィンドウへドラッグ&ドロップ
1.PNG

2. 360度写真の準備

以下のサイトなどで360度写真をダウンロードできます
360cities.net

スマホカメラでも『Googleストリートビュー』アプリなどで撮影することができるようです

今回は購入後一度だけ使用して物置きに放置されたGoPro MAXで撮影しました

3. 画像をオブジェクトにセット

①画像を「Resources/Images」フォルダへインポート
②オブジェクトに画像をセット
2.PNG
③画像のMax Sizeを変更(小さいと画像が荒くなる)
4.PNG
HierarchyウィンドウからSphere100を選択し、
④InspectorウィンドウからScaleを全て100に、
⑤ShaderをUnlit/Textureに、
⑥写真が左右反転している場合はTillngのXを-1に変更
3.PNG
⑦Shere100オブジェクトにCanvasをアタッチして、
⑧Projectウィンドウへドラッグ&ドロップでPrefab化
5.PNG
ボタンもいい感じに作ってPrefab化して、
「JumpButton」という名前でResources/Prefabsフォルダへ配置

Prefab化したオブジェクトはHierarchyから削除しておく

4. カメラ制御用のスクリプト

以下のサイトから拝借
Unity:マウスドラッグでカメラを回転して視点を操作するスクリプト

マウスホイールでズームイン/ズームアウトできるようUpdate関数に追記

CameraRotater.cs
    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

外から変数を変更できるようスクリプトに以下を追記

RadialBlur.cs
    public void SetStrength(float _strength)
    {
        this._strength = _strength;
    }
}
6. 写真の位置情報を作成

写真のそれぞれのid, xy座標, 移動先のidを設定
これを元に移動ボタンを作成します
9.PNG
これをCSVファイルにしてResourcesディレクトリに配置

CSVに対応したクラスを作成

public class PhotoPosition
{
    public int id;
    public float x;
    public float y;
    public int[] jumpTo; 
}

CSVをクラスに変換してくれる無料アセットをインポート
CSV Serialize

7. メインスクリプトの作成

以下のスクリプトを作成し、適当なオブジェクトにアタッチ

CreateSphereController.cs
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);
    }
}

WebGLアプリをビルド

Build SettingsからWebGLを選択してBuildするだけ!
7.PNG

Firebaseの設定

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などのサイトで簡単に公開できるのでオススメです!

ちなみに撮影した写真は、北海道の美幌峠から望む屈斜路湖でした。

4
5
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5