Unityでムービーをフルサイズで再生し、前ムービーと後ムービーを順に再生、さらには前ムービーを半透明にして後ムービーに重ねて同時に再生する機能を実装する方法を解説します。
この機能は、複数のムービーを滑らかに切り替えたり、同時に再生したりする際に便利です。

紹介する実装方法は、Unityのチュートリアルレベルの知識があることが前提にしています。すべての設定項目等を細かく伝えているチュートリアル的な記事ではない点をご留意下さい。
必要なスクリプトの概要
この機能を実現するためには、主に2つのスクリプトが必要です。
- MainManager.cs: ムービーの再生フローを管理するスクリプトです。
- VideoController.cs: ムービーの再生を制御し、前後のムービーを管理するスクリプトです。
必要なオブジェクト
前後に表示するようのビデオプレイヤー及び、キャンバスが2つずつと、MainManagerをコンポーネントに追加するオブジェクト、VideoControllerを追加するオブジェクトが必要になります。

ビデオプレイヤーは空のオブジェクトを作成後、コンポーネントにVido Playerを追加します。また、Target Textureには、動画を映す用にテクスチャを作成してセットします。


VideoRenderTextureの作成
Assets内でCreate=>Render Textureでテクスチャを作成します。名前をVideoRenderTextureとします。再生したい動画のサイズに合わせてSizeを設定します。

Canvasの設定
キャンバスは、動画の表示順が前後逆にならないように設定しましょう。


MainManager.cs の設定
MainManager.csは、全体のフローを管理するスクリプトです。ここでは、ムービーの再生順序や、半透明での重ね合わせを設定します。
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using System.Linq;
using DG.Tweening;
using static VideoController;
using UnityEngine.Video;
public class MainManager : MonoBehaviour
{
#region public 変数
/// <summary>
/// メインマネージャーのインスタンス
/// </summary>
public static MainManager instance;
/// <summary>
/// 動画コントローラー
/// </summary>
public GameObject videoController;
#endregion
#region private 変数
private VideoController videoC;
#endregion
#region unityのイベント処理
void Awake()
{
if (instance == null)
{
instance = this;
}
else
{
Destroy(gameObject);
}
}
private void Start()
{
//各コンポーネントの取得
videoC = videoController.GetComponent<VideoController>();
}
#endregion
#region デバッグ処理
public void debug_video_btn()
{
//ビデオ生成
StartCoroutine(FullPlayVideoAfter(VideoClipName.none, VideoClipName.mikopoppo, true));
}
public void debug_video_btn2()
{
//ビデオ生成
StartCoroutine(FullPlayVideoAfter(VideoClipName.daidaidai_pre, VideoClipName.daidaidai_after, true));
}
public void debug_video_btn3()
{
//ビデオ生成
StartCoroutine(FullPlayVideoAfter(VideoClipName.bonus_keizoku, VideoClipName.slot_atari02, true));
}
/// <summary>
/// 動画を再生します。
/// </summary>
/// <param name="clip">再生する動画クリップ</param>
private IEnumerator FullPlayVideoAfter(VideoClipName preVideoClipID, VideoClipName VideoClipID,bool isFadeOut)
{
//プレムービーが指定されている場合は再生する
if (videoC != null && preVideoClipID != VideoClipName.none)
{
//ビデオを再生
if (preVideoClipID == VideoClipName.bonus_keizoku)
{
//同時再生する場合
StartCoroutine(videoC.PlayFullScreenVideo(fullMode.PreFullScreenSame, preVideoClipID, isFadeOut: true, 0.85f));
}
else if (preVideoClipID == VideoClipName.ending)
{
//同時再生する場合
StartCoroutine(videoC.PlayFullScreenVideo(fullMode.PreFullScreenSame, preVideoClipID, isFadeOut: true, 0.4f));
}
else
{
//再生終了を待つ場合
yield return StartCoroutine(videoC.PlayFullScreenVideo(fullMode.PreFullScreen, preVideoClipID));
}
}
//フルビデオの再生
if (videoC != null && VideoClipID != VideoClipName.none)
{
yield return StartCoroutine(videoC.PlayFullScreenVideo(fullMode.FullScreen, VideoClipID, isFadeOut));
}
}
#endregion
}MainManager.csのFullPlayVideoAfterメソッドは、Unityで複数のムービーを順番に再生したり、特定の条件で重ねて再生したりするための処理を行います。このメソッドを使うことで、指定した2つのムービーを滑らかに再生することが可能です。

デバッグ用のボタンを3つ用意して、3つのパターンの動画再生デバッグ機能を用意しています。

メソッドの目的と役割
FullPlayVideoAfterメソッドは、2つのムービークリップを順番に、または重ねて再生する機能を提供します。このメソッドは以下の状況に対応します。
- 前ムービーの再生:
preVideoClipIDとして指定されたムービーがある場合、それを最初に再生します。 - 後ムービーの再生: 前ムービーの再生が完了した後、または同時に、
VideoClipIDとして指定されたムービーを再生します。 - フェードアウトの制御:
isFadeOutのフラグに応じて、再生終了時にムービーをフェードアウトさせることができます。
引数の解説
VideoController.VideoClipName preVideoClipID: 最初に再生する前ムービーの名前です。VideoClipNameは、事前に定義されたムービークリップの列挙型です。noneが指定された場合、前ムービーは再生されません。VideoController.VideoClipName VideoClipID: 次に再生する後ムービーの名前です。このムービーは、前ムービーの再生が完了した後に再生されます。bool isFadeOut: ムービー再生終了時にフェードアウトを行うかどうかを指定するフラグです。trueにするとフェードアウトが有効になります。
処理の流れ
- 前ムービーの再生:
preVideoClipIDがnoneでない場合、前ムービーを再生します。- 特定のムービー(例えば、
bonus_keizokuやending)は、後ムービーと同時に再生するため、PreFullScreenSameモードを使用します。 - 他のムービーは、
PreFullScreenモードで再生され、再生が完了するまで後ムービーの再生を待ちます。
- 後ムービーの再生:
- 前ムービーの再生が完了した後、または同時に、
VideoClipIDで指定された後ムービーをFullScreenモードで再生します。 - ここでも
isFadeOutがtrueの場合、再生後にムービーがフェードアウトします。
- 前ムービーの再生が完了した後、または同時に、
メソッドの活用例
FullPlayVideoAfterメソッドは、ゲームのシーン切り替えや特定の演出シーンで非常に役立ちます。
例えばスロット演出以外にも、ボス戦の前にイントロムービー(前ムービー)を再生し、その後、メインのボス戦ムービー(後ムービー)を滑らかに再生する、といった演出を実現することができます。
VideoController.csの主要なメソッドについて解説
VideoController.csは、実際にムービーを再生し、その表示方法を制御するスクリプトです。ここで、フルスクリーンのムービー再生や、前後のムービーを重ね合わせる処理を行います。
using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Video;
public class VideoController : MonoBehaviour
{
/// <summary>
/// 再生パターン
/// </summary>
public enum fullMode
{
PreFullScreen, //前再生待機
PreFullScreenSame, //前再生同時
FullScreen //普通のフルスクリーン再生
};
/// <summary>
/// ビデオクリップ種類
/// </summary>
public enum VideoClipName
{
haiku,
mikopoppo,
slot_atari01,
slot_atari02,
slot_atari03,
slot_atari04,
slot_atari05,
sanpai,
hikouki,
taiyaki,
bonus_keizoku,
bonus_mae,
bonus_ato,
semifinal,
soredemo,
daidaidai,
daidaidai_pre,
daidaidai_after,
ending,
mikosama,
none //noneはビデオ再生なし 一番最後に記述する
}
public Canvas cameraCanvas; // フルスクリーン再生機能用Canvas
public Canvas cameraPreCanvas; // フルスクリーン再生機能用Canvas
public VideoPlayer videoPlayerFull;
public VideoPlayer videoPlayerPreFull;
public List<VideoClip> videoClips;
public GameObject fullScreenVideoFramePrefab;
public GameObject fullScreenVideoFramePrefab2;
public RenderTexture fullScreenRenderTexture;
public RenderTexture preFullScreenRenderTexture;
public RawImage fullScreenRawImage;
public float fadeDuration = 0.1f; // フェードアウトの時間
// VideoClipを列挙型で管理するための辞書
private Dictionary<VideoClipName, VideoClip> videoClipDict;
/// <summary>
/// 起動時の初期化
/// </summary>
void Start()
{
// VideoClip辞書の初期化
videoClipDict = new Dictionary<VideoClipName, VideoClip>
{
{ VideoClipName.haiku, videoClips[0] },
{ VideoClipName.mikopoppo, videoClips[1] },
{ VideoClipName.slot_atari01, videoClips[2] },
{ VideoClipName.slot_atari02, videoClips[3] },
{ VideoClipName.slot_atari03, videoClips[4] },
{ VideoClipName.slot_atari04, videoClips[5] },
{ VideoClipName.slot_atari05, videoClips[6] },
{ VideoClipName.sanpai, videoClips[7] },
{ VideoClipName.hikouki, videoClips[8] },
{ VideoClipName.taiyaki, videoClips[9] },
{ VideoClipName.bonus_keizoku, videoClips[10] },
{ VideoClipName.bonus_mae, videoClips[11] },
{ VideoClipName.bonus_ato, videoClips[12] },
{ VideoClipName.semifinal, videoClips[13] },
{ VideoClipName.soredemo, videoClips[14] },
{ VideoClipName.daidaidai, videoClips[15] },
{ VideoClipName.daidaidai_pre, videoClips[16] },
{ VideoClipName.daidaidai_after, videoClips[17] },
{ VideoClipName.ending, videoClips[18] },
{ VideoClipName.mikosama, videoClips[19] },
};
videoPlayerPreFull.playOnAwake = false;
videoPlayerFull.playOnAwake = false;
//音量を最初から設定しておく
videoPlayerPreFull.SetDirectAudioVolume(0, 0.2f);
videoPlayerFull.SetDirectAudioVolume(0, 0.50f);
fullScreenRawImage.texture = fullScreenRenderTexture;
}
/// <summary>
/// フルスクリーンビデオを再生する
/// </summary>
/// <param name="clipName"></param>
/// <returns></returns>
public IEnumerator PlayFullScreenVideo(fullMode selectMode,
VideoClipName clipName,
bool isFadeOut = false,
float fadeRitu = 0.85f)
{
if (videoClipDict.TryGetValue(clipName, out VideoClip clip))
{
switch ( selectMode)
{
case fullMode.PreFullScreen:
videoPlayerPreFull.clip = clip;
break;
case fullMode.PreFullScreenSame:
videoPlayerPreFull.clip = clip;
break;
case fullMode.FullScreen:
videoPlayerFull.clip = clip;
break;
}
if (clipName == VideoClipName.ending) { videoPlayerPreFull.SetDirectAudioVolume(0, 0.6f); }
yield return StartCoroutine(CreateFullScreenVideo(selectMode,isFadeOut, fadeRitu));
}
else
{
Debug.LogError("Specified video clip not found.");
}
}
/// <summary>
/// フルスクリーンビデオを生成する
/// </summary>
/// <returns></returns>
public IEnumerator CreateFullScreenVideo(fullMode selectMode,
bool isFadeOut = false,
float fadeRitu = 0.85f)
{
VideoPlayer selectPlayer;
switch (selectMode)
{
case fullMode.PreFullScreen:
case fullMode.PreFullScreenSame:
selectPlayer = videoPlayerPreFull;
break;
case fullMode.FullScreen:
selectPlayer = videoPlayerFull;
break;
default:
selectPlayer = videoPlayerFull;
break;
}
GameObject fullScreenVideoFrameInstance;
// インスタンスをCanvasの子オブジェクトに設定
// ※キャンバスの表示順を利用する
switch (selectMode)
{
case fullMode.PreFullScreen:
case fullMode.PreFullScreenSame:
fullScreenVideoFrameInstance = Instantiate(fullScreenVideoFramePrefab2, transform);
fullScreenVideoFrameInstance.transform.SetParent(cameraPreCanvas.transform, false);
break;
case fullMode.FullScreen:
default:
fullScreenVideoFrameInstance = Instantiate(fullScreenVideoFramePrefab, transform);
fullScreenVideoFrameInstance.transform.SetParent(cameraCanvas.transform, false);
break;
}
RectTransform rectTransform = fullScreenVideoFrameInstance.GetComponent<RectTransform>();
rectTransform.anchorMin = new Vector2(0, 0);
rectTransform.anchorMax = new Vector2(1, 1);
rectTransform.offsetMin = Vector2.zero;
rectTransform.offsetMax = Vector2.zero;
rectTransform.pivot = new Vector2(0.5f, 0.5f);
RawImage fullScreenRawImage = fullScreenVideoFrameInstance.GetComponent<RawImage>();
if (fullScreenRawImage == null)
{
Debug.LogError("fullScreenRawImageにはRawImageコンポーネントがありません。");
yield break;
}
switch (selectMode)
{
case fullMode.PreFullScreen:
case fullMode.PreFullScreenSame:
fullScreenRawImage.texture = preFullScreenRenderTexture;
selectPlayer.targetTexture = preFullScreenRenderTexture;
break;
case fullMode.FullScreen:
default:
fullScreenRawImage.texture = fullScreenRenderTexture;
selectPlayer.targetTexture = fullScreenRenderTexture;
break;
}
//透明度の設定
switch (selectMode)
{
case fullMode.PreFullScreen:
break;
case fullMode.PreFullScreenSame:
//半透明にする
fullScreenRawImage.color = new Color(1, 1, 1, fadeRitu);
break;
case fullMode.FullScreen:
default:
break;
}
CanvasGroup canvasGroup = fullScreenVideoFrameInstance.AddComponent<CanvasGroup>();
canvasGroup.alpha = 1f;
// ビデオを再生して最初のフレームを表示
// ビデオのフレームをリセットしてから再生を開始
selectPlayer.frame = 0;
selectPlayer.Prepare();
yield return new WaitUntil(() => selectPlayer.isPrepared);
Debug.Log("ビデオは準備され、これから再生される。");
selectPlayer.StepForward();
yield return null; // 1フレーム待つ
selectPlayer.Play();
yield return new WaitForSeconds((float)selectPlayer.length);
if (isFadeOut)
{
yield return StartCoroutine(FadeOut(canvasGroup));
}
Destroy(fullScreenVideoFrameInstance);
}
/// <summary>
/// ビデオのキャンバスをフェードアウトする
/// </summary>
/// <param name="canvasGroup"></param>
/// <returns></returns>
IEnumerator FadeOut(CanvasGroup canvasGroup)
{
float elapsedTime = 0f;
while (elapsedTime < fadeDuration)
{
canvasGroup.alpha = 1f - (elapsedTime / fadeDuration);
elapsedTime += Time.deltaTime;
yield return null;
}
canvasGroup.alpha = 0f;
}
}Inspectorの設定は以下のようになっています。


rawVideoとrawVideo2は、UI=> Raw ImageにVideoRenderTextureを設定したものをプレハブ化してセットしています。透明度を2つ同時に管理する関係上VideoRenderTextureも2つセットしています。

Fade Durationで、フェードアウトの時間を調整できるようにしています。
各メソッドの説明
以下では、VideoController.csの主要なメソッドについて、初心者にもわかりやすく解説します。このスクリプトは、Unityでムービーを再生するために使用され、複数のムービーを順番に再生したり、同時に再生したりする機能を提供します。
1. PlayFullScreenVideoメソッド
説明: このメソッドは、指定されたモードとムービークリップ名に基づいてムービーをフルスクリーンで再生するための設定を行います。
fullMode selectMode: ムービーの再生方法を指定するための引数です。PreFullScreen(前ムービーをフルスクリーンで再生)、PreFullScreenSame(前ムービーを半透明で後ムービーと同時に再生)、FullScreen(後ムービーをフルスクリーンで再生)などのモードを選択します。VideoClipName clipName: 再生するムービークリップの名前を指定します。bool isFadeOut: 再生終了時にフェードアウトさせるかどうかを指定します。float fadeRitu: ムービーを半透明にする場合の透明度を指定します。
このメソッドでは、指定されたムービークリップを選択し、その後にCreateFullScreenVideoメソッドを呼び出してムービーを再生します。
2. CreateFullScreenVideoメソッド
説明: このメソッドは、指定されたモードに基づいてフルスクリーンでムービーを再生します。ムービーの準備、再生、フェードアウト処理を行います。
VideoPlayer selectPlayer: 再生するムービーのプレイヤーを選択します。selectModeによってフルスクリーン用か、半透明用のプレイヤーを決定します。Canvas targetCanvas: ムービーを表示するためのキャンバスを選択します。RawImage targetImage: ムービーを描画するためのテクスチャを設定します。CanvasGroup canvasGroup: キャンバスの透明度を管理するためのコンポーネントです。フェードアウト時に使用します。
このメソッドでは、ムービーの準備 (Prepare メソッド) が完了するまで待ち (WaitUntil メソッド)、ムービーを再生し、オプションでフェードアウト処理を行います。
3. FadeOutメソッド
説明: このメソッドは、キャンバスグループの透明度を徐々に下げて、ムービーがフェードアウトする効果を作り出します。
CanvasGroup canvasGroup: フェードアウトする対象のキャンバスグループを受け取ります。float elapsedTime: フェードアウトの経過時間を管理します。float fadeDuration: フェードアウトにかかる時間を指定します。
このメソッドでは、指定した fadeDuration の間に、キャンバスの透明度 (alpha) を徐々に下げていき、最終的に完全に透明にします。
まとめ
今回解説したVideoControllerクラスとMainManagerクラスを組み合わせることで、Unity内で高度なムービー再生機能を実装することができます。
この機能は、ゲームやアプリケーションにおいて、複数のムービーを順番に再生したり、半透明で重ね合わせたりする際に非常に有用です。
これらのスクリプトを理解し、カスタマイズすることで、Unityプロジェクトにおけるムービー演出の幅が広がり、よりリッチで魅力的なユーザー体験を提供できるようになります。
