脳汁portal

アメリカ在住(だった)新米エンジニアがその日学んだIT知識を書き綴るブログ

PlayerPrefsとStreamingAssetsにおけるファイルの扱いの違い

Player Prefs StreamingAssets
Windows Android Windows Android
バイス上で保存される場所 システムレジストリ ShaderPreferences コンパイルしたアプリのDataディレクト -
ファイル内容の修正に関して regeditで編集可能 通常不可 テキストエディタで編集可能 通常不可
アプリ初回起動時のファイルの扱い あらかじめ作成しておくことは出来ない(初回起動時にはじめて作成される) あらかじめ作成しておくことが可能
- - WriteもReadも可能 Readのみ可能(編集したい場合は初回起動時にPersistentDataディレクトリにコピーし、二回目以降はそちらを利用する方法がメジャー)
特徴 セーブデータの保存などに利用される StreamingAssets以下に配置されたファイルはアプリのコンパイル時に圧縮されない

Unityのオブジェクトをスクリプトから回転する方法

方法

YourObject.transform.Rotate (x, y, z);
YourObject.transform.rotation = Quaternion.Euler (x, y, z);

using UnityEngine;
using System.Collections;

public class Nouziru : MonoBehaviour {
    public GameObject cube;

    void  Start(){
        cube.transform.Rotate (10, 20, 30);
        ### または
        cube.transform.rotation = Quaternion.Euler (10, 20, 30);
    }
}

UnityでOculus Rift用に作成した高解像度のmp4動画がカクつくことに関する検証

UnityでOculus Rift用に動画コンテンツを作る際に、解像度によっては結構な頻度でカクつきが発生します。
原因や解決方法など色々調べたので備忘録もかねて書いておきたいと思います

Movie Texture

UnityにはWindowsプラットフォーム用にMovie Textureという機能が存在します。
これを使えば簡単に動画を再生できるのですが、動画によってはスムーズに再生されなかったり、そもそも再生されなかったりします

問題の動画

  • 解像度:4K
  • Frame rate: 25FPS
  • 動画サイズ: 350MB
  • 動画時間:120秒

そもそも再生できない問題

ファイルサイズ

350MBくらいの動画を再生しようとしたが、そもそも再生がはじまらない
編集ツールでファイルを分割して検証してみた

  • 4k + 10秒(38MB): 再生可能、ただし最初の方は映像が乱れる

⇒ファイルサイズが大きいと再生がはじまらないっぽい

フレームレート

今回検証に使った動画は25FPSだが、他の30FPSの動画を再生したところ問題なく動いた

⇒フレームレートは関係ないっぽい

再生はじめが乱れる問題

解像度
  • 4K(3842×1920)動画は再生はじめに映像が乱れる
  • 解像度を落として検証したところ・・・
    • 2K + 10秒の動画:再生可能&乱れない
    • 2K + 30秒の動画:再生可能&乱れない
    • 2K + 2分の動画:再生可能&乱れない

⇒解像度が高いと再生はじめが乱れるっぽい

考察

Unity DefaultのMovieTextureはファイルサイズが大きくなると再生自体が出来ない模様
さらに、ファイルサイズが小さくても1920pまでしか綺麗に再生できない模様


AVProVideo

Windows用に高解像度の360動画コンテンツを作る際に最もメジャーな(?)AssetであるAVProVideoでも検証してみた

普通に検証

再生は出来るが、すごいカクつく
Unityのログには以下のようなWarnログが表示される

[AVProVideo] Using software video decoder.......

対策

その1 起動オプションをつける

Unityをコマンドラインで実行し、"-force-d3d11-no-singlethreaded"オプションをつけると、warnログも消えて、表示もスムーズになる
ただし、このオプションはビルド時には反映されないため、ビルドしたアプリも同様にコマンドラインで実行して上記のオプションを指定しなければいけない

その2 Force DirectShow機能を使う

AVProVideoには前のversionとしてAVPro Windows MediaというAssetが存在し、そちらは既にAsset Storeでは公開終了しているものの、以下のサイトから無料パッケージがまだダウンロードできる
こちらを試してみたところ、カクツキなくスムーズに再生された

予想としては、

  1. AVPro Windows Mediaはcodecとして恐らくデフォルトでDirectShowを利用している
  2. しかし、AVProVideoは全プラットフォーム対応なので、Unityの標準であるQuickTimeを利用している
  3. 試しにQuickTimeで直接4kのmp4動画を再生してみたところ、Riftで見たときほどではないがカクついた

つまり、Unityが利用するcodecをDirectShowにして、適切なCodecを利用できるようにしてやれば解決する?

対策として、以下の過去ポストにしたがって、
portaltan.hatenablog.com

  1. 高解像度mp4動画を低コストで再生できるLAV filterをインストール
  2. codec tweakerでH.264再生時のデフォルトcodecをLAVに変更
  3. UnityのAVProVideoのpropertyで、Media Player > Platform Specific > Windows > Force DirectShowにチェックを入れる
  4. TimeScaleにもチェックいれておく

以上の設定を行ったところ、実行時に特別なオプションを指定しなくともスムーズに動画が再生されるようになった


注意

Force DirectShow機能は途中から導入されたようなので、古いversionだと項目自体がありません

追記

AVProVideo (Windows)だとそもそもDirectShow前提なのか項目がなかった。
替わりにHardwareDecordingの項目があって、それにチェックをいれるとスムーズに再生された。
f:id:portaltan:20161013105052p:plain

AVProVideoでOculus Rift用の360動画アプリを作成する

以前GearVR用の360動画アプリの作成方法を載せましたが、今回はOculus Rift用の開発方法を書きたいと思います
portaltan.hatenablog.com

使用ツール

AVProVideo

GearVRではEasyMovieTextureを利用しましたが、RiftではAVProVideoを利用します。
AVProVideoは色々種類がありますが、とりあえずお試しとしては全プラットフォーム対象の無料版があるので、そちらを利用するとよいかと思われます
portaltan.hatenablog.com

UnityにはデフォルトでMovieTextureという動画再生の機能がありますが、こちらは再生できる解像度が低いです。
(一応こちらがMovieTextureの使い方です)
portaltan.hatenablog.com

開発方法

1. Oculus Utilityのimport

まずはいつも通りOculusが提供しているUnity用のUtilityをimportします
Developers — Build The Future | Oculus
f:id:portaltan:20160909195713p:plain

2. AVProVideoのImport

次にAVProVideoのimportをします。
(今回はトライアル版を利用します)
http://renderheads.com/product/avpro-video/
f:id:portaltan:20160909195920p:plain

3. OVRCameraRigと360SphereVideoのPrefabの配置

まずはOVRCameraRigを配置し、次に360SphereVideoというPrefabも同様にHierarchyにD&Dで配置します
f:id:portaltan:20160909200107p:plain
(不要なMainCameraとLightは削除しました)

4. 動画の取り込み

再生したい動画ファイルをAssets/StreamingAssetsの下に配置します。
(今回はAVProVideoをimportするとデフォルトでついてくるSampleSphere.mp4を利用します)

5. 動画の指定

次に取り込んだ動画を再生対象として指定します

  1. 360SphereVideoの子オブジェクトのAVPro Video Media playerオブジェクトのInspectorを開きます。
  2. Media Player(Script)の緑色のボタン(BROWSE)を選択します
  3. 動画を選択するウィンドウが開くので再生したい動画を選択します

f:id:portaltan:20160909200530p:plain

6. 確認

以上で設定は完了です。Editorの再生ボタンを押して実際に再生されることを確認しましょう
f:id:portaltan:20160909201131p:plain

UnityのApplication.Quit()がWindows環境でフリーズしたりしなかったりする

Application.Quit()によるアプリのフリーズ

Unityのversionを5.3.6p1にあげたところ、Application.quit()が動いたり動かなかったりするようになってしまいました
動かないときはアプリ自体がフリーズして最終的にはクラッシュしてしまいます

調べてみると色々なversionで多くの人が同じ問題に遭遇しているらしいのですが、根本的な原因に関しての記述は見つかりませんでした。

対応策も人によって様々なのですが、自分がうまくいった方法は、Application.quit()後すぐにreturnして、明示的にそれ以降の処理をスキップさせる方法です

void Update ()
{
    if (終了させるためのトリガー){
        Application.Quit();
	return;
    }

    // 以降いろんな処理
}

これでいまのところは正常に動いています。

GoPro6台で360動画を撮影して貼り合わせる方法(定点撮影)

GoPro6台でジグを利用して動画を撮影し、Kolorを利用してスティッチしてEquireqtangular形式の360動画を作成するまでの流れです

利用した機材・ツール

  • GoPro Hero4 Black Adventure × 6台

  • GoPro用ジグ

  • GoPro用リモートコントローラ(Smart Remote)

  • SDカード
  • Kolor Autopano Video

Kolor | Autopano Video - Video stitching software

手順

撮影

1. GoPro設定

水中ケースからGoProを外して設定を行います
各種設定項目は以下を参照してください
http://freedom360.us/camera-settings/
注意点としては、6台用のジグを利用する場合アスペクト比は4:3でないとうまくスティッチができません

2. Wifiリモコンとのペアリング

GoPro本体側の設定
GoPro用のリモコンであるSmart Remoteとペアリングをします
GoPro左側面にあるボタンを押して、設定画面を表示させます
Wifi』の項目からペアリングモードを開始できます。
(3分間ペアリング状態になり、3分経ってもペアリングしないと終了します)

リモコン側の設定
この状態でリモコンの赤い丸ボタンを押しながら、電源ボタンを一度押します
リモコンがペアリングモードで起動し、GoPro本体とペアリングが開始します
無事ペアリングが完了すると6CAM/READYという表示がリモコン側に表示されます

3. ジグに装着する

設定の完了したGoProをジグに取り付けます

4. 撮影

リモコンの赤い丸ボタンを押すとペアリングされているGoPro全台で録画が開始します。
ただし一台のリモコンから同時に信号を送ったとしても、各GoProが録画を開始するタイミングには若干のラグがあります。
あとでタイミングを合わせるための目印として、撮影の最初か最後のに手を叩いて音を出しておきます。

撮影が終わったらもう一度赤いボタンを押せば録画終了です。

5. 動画の取り込み

SDカードから、もしくはUSBケーブルをGoPro本体へ接続して撮影したmp4データをPCに取り込みます

貼り合わせ

ここからはkolor社のAutopano Videoというツールを利用し、6台分の映像データを貼り合わせて一つの360動画にしていきます

1. AutoPano Video起動&動画読み込み

AutoPano Videoを起動すると以下のようなウィンドウが表示されます
f:id:portaltan:20160905093714p:plain

D&Dで映像ファイルを6つまとめてAutopano Videoに取り込みます
f:id:portaltan:20160905094047p:plain

2. 動画のシンクロナイズ

撮影の項目で書きましたが、GoProで撮影した6つの動画ファイルは少しずつ(1秒以下ですが)再生開始時間がずれています。
まずはこのずれを修正します。
f:id:portaltan:20160905095550p:plain
1. 下半分の秒数が表示されている項目から、手を叩いたのがおおよそ何秒くらいだったか調べます
2. 次にSychroという項目を選択します
3. Search range around current timeに、上記で調べた手を叩いたおおよその秒数を入力します
4. Use audio to synchronizeをクリックします
 (目印となる音がない場合は、隣のUse motion to synchronizeを選択します)
5. autopano videoが指定された秒数の前後から目印となる音を自動で探し出してくれます
6. Nearrest frameにそれぞれのGoProのずれが表示されるので、あまりにも大きな数字がなければ、右下のApplyを選択して、自動で検出した目印を基にシンクロナイズします

3. 簡易スティッチ(貼り合わせ)

次に動画を貼り合わせます
シンクロの隣のStichという項目を選択します
スティッチの設定画面が出てきます

  • 一番上の項目(Stitch as)が『GoProHero3+/4』になっていることを確認します
  • 中段の項目(Stich at)が『Current position』になっていることを確認
    • current position: 現在の再生ポジションのみを参考にスティッチを行う(カメラを固定した定点撮影のときのみ利用)
    • current selection: 設定した数だけランダムにframeを抜き出して、それらをもとにスティッチを行う(最大99frame)

スティッチが完了すると上段の一番右にRealtime previewという名前でEquirectangular形式の画像が表示される
f:id:portaltan:20160905100952p:plain

4. レンダリング

最後は普通にRenderという項目を選択してレンダリングをすればEquirectangular形式のmp4ファイルがレンダリングされます。

5. 確認

作成した360動画をOculusなどのHMDで見る方法はいくつかありますが、同じくkolor社のGoPro VR Playerを使うのが一番簡単かと思います。
Kolor | GoPro VR Player - Watch 360-degree videos and images offline

注意点とか

  • AutoPano Videoによる自動スティッチは精度があまり高くありません。きちんとやる場合はAutopano Gigaというツールで手動でスティッチする必要があります
    • (ただしこちらは少し使い方が難しく、もう少し詳しくなったらまた別でブログに書きたいと思います)
  • 6台で撮影する際は、メインの被写体がカメラとカメラのつなぎ目に位置しないように注意した方がいいです
    • (3台のカメラに跨って映っていたりするとスティッチがかなり面倒くさくなります)
  • 今回は手を叩いた音でシンクロナイズをしましたが、motionによってシンクロナイズすることも可能です。

Unityをコマンドラインからオプションを指定して起動する

通常Unityは立方体のUnityのアイコンをクリックして立ち上げるが、コンソールから実行するとコマンドライン引数としてオプションを指定することができる
Unity - マニュアル: コマンドライン引数

Windows環境の場合はコマンドプロンプトで以下のように実行する

起動

> cd "\Program Files\Unity\Editor"
> Unity.exe

ビルド

> cd "\Program Files\Unity\Editor"
> Unity.exe -quit -buildWindows64Player <pathname>
  • 64bit スタンドアロン Windows player をビルドする場合
  • quitをつけるとbuildが終わるとアプリを自動で終了する

オプションの指定

> cd "\Program Files\Unity\Editor"
> Unity.exe <option>
> Unity.exe -force-d3d11-no-singlethreaded ### example

ちなみにここで指定したオプションはビルド時には反映されないが、ビルドされたアプリケーションもコマンドラインから起動することで上記のオプションを指定することができる

> ${buildしたアプリ}.exe -force-d3d11-no-singlethreaded