【Unity入門】OculusGoで動画再生・停止させて遊んでみた♬


今回は、動画を再生表示させてみました。

Unityでは以下の参考(1)があるのでほぼまんま参考にさせていただきました。
参考(2)は、たぶんVideoPlayer以前のお話で、こちらは大変苦労されているという例として載せました。
【参考】
(1)UnityでVideoPlayerを使って動画の再生・停止をさせる
(2)Oculus 3D動画を見る方法 -4-

動画を見るということでも、Unityはかなりバリエーションが豊富です。
それは、ゲーム作成というシーンでいろいろなバリエーションが考えられるからでしょう。
しかし、ここでの興味は一応VR内で物体検出したいという目的なので、今回もある意味さらりと分かりやすくを心がけたいと思います。

やったこと

(1)OculusGoを使う設定をする
(2)動画をimport new assetsする
(3)VideoPlayerをOVRCameraRigに張り付けて設定する
(4)Unityで実行▶する
(5)OculusGo向けの設定をしてBuild&Runする
(6)OculusGoで実行する
(7)OculusGoで再実行する
(8)動画のためのUIを張り付けて設定する
(9)Canvas上の動画をコントロールする準備
(10)マウス操作で動画再生・停止を操作する
(11)audioの追加と停止・再生

(1)OculusGoを使う設定をする

①新しいPJを作成する。Oculusのassetsをインポートする。
 #聞かれるのでOculusにチェックを入れて起動する
②Main Cameraを削除して、Project-Oculus-VR-Prefabs-からOVRCameraRigを選んでHierarchyにドラッグドロップする。

(2)動画をimport new assetsする

①Assets-import New Assets...-で適当な動画ファイル(mp4, aviが動きました)をimportする

(3)VideoPlayerをOVRCameraRigに張り付けて設定する

①Hierarchyで右クリック、Video-VideoPlayerでVideoPlayerをHierarchyに張り付けて、OVRCameraRig配下にドラッグドロップする。
②VideoPlayerの設定する。
 まず、VideoPlayerをクリックするとプロパティがInspectorに出現する。そこで、Video Clipとして、先ほどImportしたファイルを設定する。Video Clipの右側にある〇マークをクリックするとSelect VideoClipの窓枠が表示され、窓枠内に先ほどImportしたファイル(複数の場合は複数)があるから表示したい動画をダブルクリックするとVideoClipにファイル名が表示される。
②TransformのPositionを「X:0,X:Y:0,Z:0」、Rotationを「X:90,Y:270,Z:90」とする

(4)Unityで実行▶する

以上の設定で以下のような設定になっていると思う。

以下のように、実行すると動画が表示されるはずである。
ちなみに、左下の動画が動いています。

(5)OculusGo向けの設定をしてBuild&Runする

①以前と同じように、OculusGo向けに以下設定する
「File-BuildSettings..」でBuild Settingsを表示
Androidをクリックすると、下にSwitchPlatformがForcusするので、それをクリックすると以下のような画面になります。

②Player SettingsをクリックしてInspectorにPlayerSettingsを表示させて以下三か所変更します。
一つは、OtherSettingsのPackage nameを適当な名前(com.muauna.video2)にする。※ここは変えなくても動くこともありますが、変えた方があとで(OculusGo内で提供元不明リストから選ぶとき)に識別しやすいです
二つ目は、OtherSettingsのMinimumAPILevelを。。。(APILevel 21)にします。
三つ目は、XRSettingsのVirtualRealitySDK'sを+を選んでOculusをクリックします。

(6)OculusGoで実行する

これでBuild&RunすればOculusGoで動きます。
一応、Unityで実行して正しく動くことを確認してください。
OculusGoをUSBケーブルでつなげてからBuild&Runしてみましょう。
apkのファイル名を聞いてくるので、適当な名前(test13)を入力します。
これでコンパイルとアプリのOculusGoへの転送が終了すると静かになります。
その後、OculusGoを被ってリモコンで横〇のところを押していけば自動的に立ち上がります。最初は許可を求められると思いますが、許可をしてください。
終了も横〇押せば終了してOculusGoの画面に入ります。

動かない場合は「Edit-Preferences」でUnity PreferencesのExternal ToolsのAndroidの SDK,JDKがきちんとリンクされていることを確認しましょう。
されていない場合は、ダウンロードしてリンクを貼ってください。また、いろいろ弄っているうちに、入っていても検出しなくなる場合もありました。その場合はProjectを再起動すると認識してくれました。

(7)OculusGoで再実行する

OculusGoの画面で、ライブラリー提供元不明ースクロールで先ほどのPackageNameで付けた名前が出てくると思います。
これを一度クリックして、再度クリックするとアプリが起動します。

以上で動画を見るという初期目標は達成しましたが、これだと動画のハンドリングができそうにないので、少し遊んでみます。

(8)動画のためのUIを張り付けて設定する

UIとしては、PlaneとCanvasがよさそうです。
ということで、
①Planeを張り付けてOVRCameraRig配下に置く
②AddComponent-Layout-RectTransformを選んで、TransformをRectTransformに変更し、「Pos X:1,Pos Y:0,PosZ:10」、Rotation 「X:90,Y:27,Z:90」あたり(見えるよう)に設定する。
③PlaneにVideoPlayerをAddComponentで追加する
設定は、上記の設定と同じです。
Video Clipにimportした動画を張り付ける
とりあえず、Render ModeをMaterialOverrideとする。
。。。
これでとりあえず動いて、Planeに動画が張り付いていると思います。
同時に先ほどの大きいのが後ろで動いていると思います。
ここで先ほどのが前で動いていたら、それは先ほどのVideoPlayerのRenderModeがCameraNearPlaneになっていると思われますので、CameraFarPlaneに変更してみてください。そして再度実行すれば、Planeに張り付いた動画が見えると思います。
後ろで先ほどの動画も動いていますが、。。
まあ、これでRenderModeの役割は少しわかりますね。

(9)Canvas上の動画をコントロールする準備

まず形として、Hierarchy上で右クリックして、「UI-RawImage」を選んで張り付けます。Canvasの下に張り付いたと思います。
ここで、上記で作成したVideoPlayerをRawImageの下にドラッグドロップしてください。
※ここは参考(1)のRenderer Texture以降を見ながら読んでください。
VideoPlayerの中のRenderModeのRenderTextureを使います。
ます、Projectのところで右クリックして、Create-RenderTextureを選んで、NewRenderTextureを作成してください。
次に先ほどのRawImageをクリックして、Textureのところの右側の〇をクリックすると左上に以下のような窓が開いて、NewRenderTextureを選べると思います。
これをダブルクリックして指定します。

次にCanvasのRenderModeをWorldSpaceに変更します。
また、以下のとおりにPosX等を変更します。

ここで、RawImageのSettingは上記のNewRenderTexture含め以下のとおりです。
表示させるためにPositionとRotationの数字は大切です。

Canvas最後列のVideoPlayerのSettingsは以下の通りです。WorldSpaceにしたので、Positionが自動的に大きく変化しています。

最後に全体の表示バランスを考えて、Planeの座標等も以下のように変更しています。ここはあくまでどう表示したいかで決めてください。

これ実行すると以下のとおり正常に動画が表示されます。

(10)マウスで動画再生・停止を操作する

この項もほとんど参考(1)のまんまです。

①Projectで右クリックーCreate-C#script-で、MoviePlayerという名前で以下の参考(1)のコードをコピペして作成します。
②MoviePlayerをドラッグドロップして、VideoPlayerに張り付けます。
 そして、RawImageのMoviePlayerのR ImageとしてRawImageを選びます。
 さらに、RawImageのTextureをNone(Texture)に変更します(右側の〇クリックして窓から選ぶ)。
③RawImageのTextureはスクリプトから設定するので空にしておきます
④VideoPlayerのRenderModeをAPI onlyとして、rImage.texture = mPlayer.texture;により、RawImageのTextureに動画を上書きするようにします。

以上で、めでたくUnity上ではマウス操作、そしてOculusGoでもポインターで操作できました。
しかし、OculusGoのポインターは以下の”Fire1”だとポインターの前の奴だけでなく、上面をさすったり押したりして反応して止まってしまいました。だからということで、以前のようにInput.GetButtonDown ("Fire1")をInput.GetMouseButtonDown (1)と変更しても同じ挙動になりました。
※残念

(11)audioの追加と停止・再生

audioの追加は、そもそも以下のコードでは記載されているが、上記の手順でRawImageだと自動的には追加されなかった。そこで、AddComponentで以下のように追加した。

そして、AudioClipとしてはNoiseをそして、OutputはMasterとしたところ、ノイズがざーと出力された。
しかし、これを制御すべくmPlayer.EnableAudioTrack(0, false);をマウスボタンのところに配置してみたが、何にも変化なく、動画は止まってもザーは止まらない。。。これについても宿題としたい。

【追記2018.6.18】
音声持ってる動画を張り付けて、以下のとおり設定し、動画音声にするとポインター操作で動画停止とともに動画音声が停止しました!

まとめ

・OcululGoで動画+音声を張り付けて鑑賞できた
・動画の停止・再生をマウスで実施できた
・動画の種類は物体検出のアプリで使ったmp4とaviを再生できた

・マウス操作は、Unityでは右クリック左クリックなどの差がはっきり出たが、OculusGoではマウス操作はどのポインターのアクションでも同じ反応を示した。
・音声については、コードの解釈含めこれから解明したい
 ⇒音声持っている動画を使うと、元のコードで上記のようにコントロールできました。

参考(1)のコード

MoviePlayer.cs
using System.Collections;
using UnityEngine;
using UnityEngine.Video;
using UnityEngine.UI;

public class MoviePlayer : MonoBehaviour {

    // VideoPlayerコンポーネント
    private VideoPlayer mPlayer;
    // AudioSourceコンポーネント
    private AudioSource audioSource;
    // 内部に保存したテクスチャを表示するRawImageUI
    public RawImage rImage;
    // 内部スクリプトを出力するUIにTextureをセットしたかどうか
    private bool check = false;

    // Use this for initialization
    void Start () {
        mPlayer = GetComponent <VideoPlayer> ();
        // スクリプトでAudioOutputModeをAudioSourceに変更
        mPlayer.audioOutputMode = VideoAudioOutputMode.AudioSource;
        // Directモードはまだサポートされていない為使えない
//      mPlayer.audioOutputMode = VideoAudioOutputMode.Direct;
        audioSource = GetComponent <AudioSource> ();
        // オーディオトラックを有効にする
        mPlayer.EnableAudioTrack (0, true);
        // AudioOutPutがAudioSourceの時にスクリプトからAudioSourceを設定する。
        mPlayer.SetTargetAudioSource (0, audioSource);
        // スタートした時にすぐ再生する
        mPlayer.Play ();
    }

    // Update is called once per frame
    void Update () {
        // 内部に保存しているテクスチャを設定
        if (mPlayer.texture != null && !check) {
            Debug.Log ("Set");
            rImage.texture = mPlayer.texture;
            check = true;
        }
        // マウスの左クリックで再生と停止を切り替える
        if (Input.GetButtonDown ("Fire1")) {
            // 再生中でなければ再生
            if (!mPlayer.isPlaying) {
                mPlayer.Play ();
            // 再生中であれば停止
            } else {
                mPlayer.Pause ();
            }
        }
    }
}