Unity Recorder+TimeLineを使って動画を作る時に、Video Playerがずれる問題

TimeLineですべてを合わせるには 再生ボタンを押した後、一瞬TimeLineを再生&停止して

音源や動画などの読み込み時間を待ってから、TimeLineをスタートします。

プロジェクト設定

  • 品質→VSync 数 を同期しない

Playable Director

  • 更新方法 Update Method ゲーム時間 GameTime
  • ゲーム開始時に再生をオフ
  • Playable Director Startのモードは、再生使用時は再生モードで、Unity Recorder時はRecording Modeに設定を推奨

全ての動画の読み込みが終わった後1秒後にPlayable Directorを開始するコード

PlayableDirectorStart.cs
using System.Collections;
using UnityEngine;
using UnityEngine.Playables;

public class PlayableDirectorStart : MonoBehaviour
{
    private PlayableDirector director;
    public enum TimelineMode
    {
        PlayMode,
        RecodingMode,
    }

    public TimelineMode mode;

    void Start()
    {
        director = GetComponent<PlayableDirector>();
        if (director == null)
        {
            this.enabled = false;
        }
        else
        {
            director.timeUpdateMode = DirectorUpdateMode.GameTime;
            director.playOnAwake = false;
            director.Play();
            director.Stop();
            director.time = 0;
            StartCoroutine(DelayCoroutine());
        }
    }

    private IEnumerator DelayCoroutine()
    {
        bool all_preload = false;
        do
        {
            all_preload = true;
            videoSync[] syncs = FindObjectsOfType<videoSync>();
            foreach (videoSync sync in syncs)
            {
                if (!sync.preloaded)
                {
                    all_preload = false;
                    break;
                }
            }

            yield return new WaitForSeconds(1);
        }
        while (!all_preload);

        director.Play();
    }

}

VideoPlayerの設定

  • ゲーム再生時に再生をオフ
  • DirectorにPlayableDirectorのゲームオブジェクトを設定

Video PlayerをTimeLineの時間に合わせて同期をとるスクリプト

再生モード

動画の再生時間がタイムラインより早かったら一時停止して、 遅かったら1Step進める

Recording Modeモード

スクリプトで再生速度を0にして、 TimeLineの時間を取得して動画の場所を設定する

VideoSync.cs
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Video;

public class videoSync : MonoBehaviour
{
    private VideoPlayer videoPlayer;
    public PlayableDirector director;
    private bool playmode;
    [HideInInspector]
    public bool preloaded = false;

    void Start()
    {
        preloaded = false;
        videoPlayer = GetComponent<VideoPlayer>();
        if (videoPlayer == null || director == null)
        {
            this.enabled = false;
        }
        else
        {
            playmode = director.GetComponent<PlayableDirectorStart>().mode == PlayableDirectorStart.TimelineMode.PlayMode;
            videoPlayer.playOnAwake = false;
            if (playmode)
            {
                videoPlayer.playbackSpeed = 1f;
            }
            else
            {
                videoPlayer.playbackSpeed = 0f;
            }
            videoPlayer.prepareCompleted += PrepareCompleted;
            videoPlayer.Prepare();
        }
    }

    void PrepareCompleted(VideoPlayer vp)
    {
        vp.prepareCompleted -= PrepareCompleted;
        vp.Play();
        vp.Pause();
        vp.frame = 0;
        preloaded = true;
    }

    private void Update()
    {
        if (preloaded && director.state != PlayState.Paused)
        {
            if (playmode)
            {
                videoPlayer.Pause();
                if (videoPlayer.frame / videoPlayer.frameRate < director.time)
                {
                    videoPlayer.StepForward();
                    videoPlayer.Play();
                }
            }
            else
            {
                videoPlayer.frame = (long)(director.time * (double)videoPlayer.frameRate);
                videoPlayer.Play();
            }
        }
    }
}

Audio Source

  • ゲーム開始時に再生をオフ

TimeLine

Unity Recorderの設定

  • Recording ModeをManual
  • Playbackを定数 Constant
  • Cap FPSをオン