【Unity】VideoPlayerの使い方 – 動画再生をマスターしよう!
ゲームやアプリの操作説明など、Unityに動画をインポートし、再生したい場面が多々あると思います。
今回は、VideoPlayerを使って動画を再生する方法を、例を交えながらご紹介します。
取り込んだ動画の扱い方に先ずは触れて、スクリプトを使わない再生方法、スクリプトを使った高度な再生方法の順に説明していきます。
Contents
動画をインポートする(VideoClip)
VideoPlayerの前に、Unityにおける動画の扱い方をご説明します。
任意の動画をインポートし、インスペクタを開いてみましょう。
なお、今回の例ではOleg Magni氏の動画を使わせて頂きます。
Unityが扱える動画の拡張子は、.mp4、.mov、.wmvなど で、インポートされるとVideoClipというオブジェクトとなります。基本的にこのままの状態ですぐ使えますが、オプションについても詳しく見ておきましょう。
プロパティ | 機能 |
Deinterlace | インターレースするか否か |
Off | しない |
Even/Odd | 偶数/奇数行を描画 |
Flip Horizontally | 水平方向に裏返す |
Flip Vertically | 垂直方向に裏返す |
Import Audio | 音声をインポートするか否か |
Transcode | プラットフォーム毎の設定 |
※補足: インターレースというのは、動画の描画方式の1つで、 各フレームを1行おきに走査 していきます。画質は落ちますが、時間当たりのフレーム数を稼げるので、より滑らかに見せることができる訳です。
※注意: MovieTextureは将来サポートされなくなるので、その説明は省略します。VideoPlayerと比較した使用例が公式ドキュメントにあるので、詳しくはそちらをご覧ください。
VideoPlayerを使って動画を再生する
早速、インポートした動画をVideoPlayerで再生してみましょう。
ここでは、描画先をオブジェクト(Plane)、UI(RawImage)とする際の手順をご紹介します。
VideoPlayerの各プロパティについても付記します。
Planeに描画
先ず、シーンにPlaneを追加し、任意の位置・サイズを設定して下さい。これが動画を描画するスクリーンとなります。
次に、PlaneのAdd Componentから、VideoPlayerを追加して下さい。
最後に、動画をVideoPlayerのVideoClipにアタッチすれば、準備完了です。
RawImageに描画
シーンにRawImageを追加し、VideoPlayerコンポーネントを追加するところまでは先ほどと一緒です。
RenderModeがRenderTextureを選択していることを確認 し、適当に用意したRenderTextureをTargetTextureにアタッチして下さい。同じRenderTextureを、RawImageのTextureにもアタッチすれば、準備完了です。
VideoPlayerのプロパティ
インスペクタから設定できるプロパティは、次表の通りです。
全プロパティについては、公式ドキュメントをご覧ください。
プロパティ | 機能 |
Source | 動画ソース |
VideoClip | 指定したVideoClip |
URL | 指定したURLのファイル |
PlayOnAwake | Awakeで再生開始するか否か |
WaitForFirstFrame | 最初のフレームが準備できるまで待つか否か |
Loop | ループさせるか否か |
SkipOnDrop | 実時間に合わせてフレームを落とすか否か |
PlaybackSpeed | 再生速度 |
RenderMode | レンダリング方法 |
Camera Far/Near Plane | カメラ映像の奥/手前の画面 |
RenderTexture | RenderTexture |
MaterialOverride | マテリアルのテクスチャ |
Renderer | レンダリング先 |
AudioOutputMode | 音声の出力方法 |
None | ミュート |
AudioSource | 指定したAudioSource |
Direct | 端末で直接出力 |
VideoPlayerをスクリプトから使う
今度はスクリプトからVideoPlayerを操作し、より高度な再生方法を設定してみましょう。
ここでは、ボタンで再生を制御する例、複数のVideoClipを再生する例をご紹介します。
一時停止ボタン
ボタンで動画を一時停止するのが目標です。
スクリプトからVideoPlayerを使う例としては、最もシンプルなものではないでしょうか。
次のスクリプトを作成し、スクリーンにアタッチして下さい。
ボタンに関しては、以下の記事をご覧ください。
(関連記事:【Unity uGUI】ボタン(Button)の基本的な使い方を徹底解説!)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
using UnityEngine; using UnityEngine.Video; public class CustomVP : MonoBehaviour{ public VideoClip videoClip; public GameObject screen; void Start(){ var videoPlayer = screen.AddComponent<VideoPlayer>(); // videoPlayeコンポーネントの追加 videoPlayer.source = VideoSource.VideoClip; // 動画ソースの設定 videoPlayer.clip = videoClip; videoPlayer.isLooping = true; // ループの設定 } public void VPControl(){ var videoPlayer = GetComponent<VideoPlayer>(); if(!videoPlayer.isPlaying) // ボタンを押した時の処理 videoPlayer.Play(); // 動画を再生する。 else videoPlayer.Pause(); // 動画を一時停止する。 } } |
上記スクリプト(CustomVP)のVideoClipとScreenを設定し、ボタンにVPControl関数を結びつければ、準備完了です。
複数のVideoClip
複数の動画を連続再生するのが目標です。
今回はコルーチンという機能を使います。これ自体についての詳しい説明は、後述の補足をご覧ください。
次のスクリプトを作成し、スクリーンにアタッチして下さい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Video; public class MultiVP : MonoBehaviour{ public List<VideoClip> videoClipList; public bool loop; [HideInInspector] private List<VideoPlayer> videoPlayerList; [HideInInspector] private int videoIndex = 0; void Start(){ StartCoroutine(playVideo()); // コルーチンの呼び出し } IEnumerator playVideo(bool firstRun = true){ // コルーチンの宣言 int listLen = videoClipList.Count; if(videoClipList == null || listLen <= 0){ Debug.LogError("Assign VideoClips from the Editor"); yield break; } if(loop) // ループの処理 videoIndex %= listLen; // インデックスを戻す。 else{ if(videoIndex>=listLen) yield break; // 全再生が終了したら、ここでコルーチンを途中終了する。 } if(firstRun){ // 最初に呼び出された時にのみ実行する処理 videoPlayerList = new List<VideoPlayer>(); for(int i=0; i<listLen; i++){ GameObject vidHolder = new GameObject("VP" + i); vidHolder.transform.SetParent(transform); VideoPlayer videoPlayer = vidHolder.AddComponent<VideoPlayer>(); // videoPlayeコンポーネントの追加 videoPlayerList.Add(videoPlayer); videoPlayer.playOnAwake = false; // trueとすると、音声と動画がずれてしまう。 videoPlayer.source = VideoSource.VideoClip; // 動画ソースの設定 videoPlayer.clip = videoClipList[i]; videoPlayer.isLooping = false; // trueとすると、次のVideoClipが再生されない。 videoPlayer.renderMode = VideoRenderMode.MaterialOverride; // レンダリング方法の設定 videoPlayer.targetMaterialRenderer = GetComponent<Renderer>(); // レンダリング先の設定 videoPlayer.audioOutputMode = VideoAudioOutputMode.Direct; // 音声の出力方法の設定 } } videoPlayerList[videoIndex].Prepare(); // 再生に際した準備をする。 while(!videoPlayerList[videoIndex].isPrepared) yield return null; // 準備中は、ここでコルーチンを中断する。 videoPlayerList[videoIndex].Play(); // 動画を再生する。 while(videoPlayerList[videoIndex].isPlaying) yield return null; // 再生中は、ここでコルーチンを中断する。 videoPlayerList[videoIndex].Stop(); // 動画の時刻を0に戻す。 videoIndex++; // インデックスを進める。 StartCoroutine(playVideo(false)); // 反復処理中に呼び出された時は、中盤の処理を省く。 } } |
これまではVideoPlayerコンポーネントをPlaneオブジェクト自体に追加しましたが、この例のように 別個にVideoPlayerオブジェクトを用意する 方法もあります。
最後に、VideoClipListのサイズを指定し、そこへ各VideoClipをアタッチすれば、準備完了です。
※補足: コルーチンとは、 反復処理中で呼び出す際に中断・再開が可能な関数のようなもの です。C#ではIEnumeratorとして宣言し、次のように扱います。
- 呼び出し: StartCoroutine(“name”)
- 中断: yield return null
- 中断(時間指定): yield return new WaitForSecond()
- 途中終了: return break
- 終了: StopCoroutine(“name”)
おまけ1:別音声を付ける
動画のとは別の音声(BGMなど)を付けたい場合は、AudioSourceコンポーネントを使いましょう。
VideoPlayerをミュートし、スクリーンにAudioSourceコンポーネントも追加 すれば完了です。AudioSourceの扱い方は、今回のVideoPlayerと非常によく似ています。
復習も兼ねて、ぜひ実装してみましょう。
おまけ2:パノラマ・シアターを作る
パノラマで撮った画像・動画を再生したい場合は、PlaneではなくSphereの内側に描画しましょう。
球に次のシェーダを掛けるだけです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
Shader "Custom/PanoPartial"{ Properties{ _MainTex("Texture", 2D) = "white" {} _xScale("xScale", Range(0, 1)) = 0.3 // 水平方向の縮尺 _yScale("yScale", Range(0, 1)) = 0.3 // 垂直方向の縮尺 _dx("xDisplacement", Range(0, 1)) = 0 // 水平方向の変位 _dy("yDisplacement", Range(0, 1)) = 0.5 // 垂直方向の変位 } SubShader{ Cull Front // 球面の表側は描画しない。 Pass{ CGPROGRAM #pragma vertex vert #pragma fragment frag sampler2D _MainTex; float _xScale, _yScale; float _dx, _dy; struct appdata{ float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f{ float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; v2f vert (appdata v){ v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } fixed4 frag (v2f i) : SV_Target{ float2 uv; uv.x = 1 - i.uv.x; // 水平方向に裏返す。 uv.x = (uv.x - _dx) / _xScale; uv.y = (i.uv.y - _dy) / _yScale; if(i.uv.x<=_dx || i.uv.x>=(_dx + _xScale)){ // 余白を塗りつぶす。 return fixed4(0, 0, 0, 1); } if(i.uv.y<=_dy || i.uv.y>=(_dy + _yScale)){ return fixed4(0, 0, 0, 1); } return tex2D(_MainTex, uv);; } ENDCG } } } |
シェーダに関して詳しく学びたい方は、以下の記事をご覧ください。
(関連記事:【Unity】Shader Graphの使い方を分かりやすく解説!シェーダーとは?)
まとめ
以上、VideoPlayerを使って動画を再生する方法のご紹介でした。
双眼表示のシェーダも組み合わせれば、すぐさまVRシアターを作ることができます。
AudioSourceやシェーダと併せて、ぜひ色々いじってみて下さい。
それでは、楽しいXR開発を!
(関連記事:【Unity】スマートフォンをARゴーグル化する方法)
この記事はいかがでしたか?
もし「参考になった」「面白かった」という場合は、応援シェアお願いします!