【Unityゲーム開発】ムービーをフルサイズで再生・前後にムービーを半透明で重ねる機能の作成方法【備忘録】

Unityでムービーをフルサイズで再生し、前ムービーと後ムービーを順に再生、さらには前ムービーを半透明にして後ムービーに重ねて同時に再生する機能を実装する方法を解説します。

この機能は、複数のムービーを滑らかに切り替えたり、同時に再生したりする際に便利です。

紹介する実装方法は、Unityのチュートリアルレベルの知識があることが前提にしています。すべての設定項目等を細かく伝えているチュートリアル的な記事ではない点をご留意下さい。

目次

必要なスクリプトの概要

この機能を実現するためには、主に2つのスクリプトが必要です。

  1. MainManager.cs: ムービーの再生フローを管理するスクリプトです。
  2. 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.csFullPlayVideoAfterメソッドは、Unityで複数のムービーを順番に再生したり、特定の条件で重ねて再生したりするための処理を行います。このメソッドを使うことで、指定した2つのムービーを滑らかに再生することが可能です。

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

メソッドの目的と役割

FullPlayVideoAfterメソッドは、2つのムービークリップを順番に、または重ねて再生する機能を提供します。このメソッドは以下の状況に対応します。

  1. 前ムービーの再生: preVideoClipIDとして指定されたムービーがある場合、それを最初に再生します。
  2. 後ムービーの再生: 前ムービーの再生が完了した後、または同時に、VideoClipIDとして指定されたムービーを再生します。
  3. フェードアウトの制御: isFadeOutのフラグに応じて、再生終了時にムービーをフェードアウトさせることができます。

引数の解説

  • VideoController.VideoClipName preVideoClipID: 最初に再生する前ムービーの名前です。VideoClipNameは、事前に定義されたムービークリップの列挙型です。noneが指定された場合、前ムービーは再生されません。
  • VideoController.VideoClipName VideoClipID: 次に再生する後ムービーの名前です。このムービーは、前ムービーの再生が完了した後に再生されます。
  • bool isFadeOut: ムービー再生終了時にフェードアウトを行うかどうかを指定するフラグです。trueにするとフェードアウトが有効になります。

処理の流れ

  1. 前ムービーの再生:
    • preVideoClipIDnoneでない場合、前ムービーを再生します。
    • 特定のムービー(例えば、bonus_keizokuending)は、後ムービーと同時に再生するため、PreFullScreenSameモードを使用します。
    • 他のムービーは、PreFullScreenモードで再生され、再生が完了するまで後ムービーの再生を待ちます。
  2. 後ムービーの再生:
    • 前ムービーの再生が完了した後、または同時に、VideoClipIDで指定された後ムービーをFullScreenモードで再生します。
    • ここでもisFadeOuttrueの場合、再生後にムービーがフェードアウトします。

メソッドの活用例

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プロジェクトにおけるムービー演出の幅が広がり、よりリッチで魅力的なユーザー体験を提供できるようになります。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次