5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

UnityのTimelineでVideoPlayerを同期したい

Last updated at Posted at 2024-09-27

Unityで動画の再生に合わせて字幕を表示したり、何かしらの演出を行いたいことがあります。

VideoPlayerをTimelineに入れてコントロールできるようなのですが、入れるだけでは動画を停止やシークした際にTimelineとの同期が取れず、試行錯誤したので対応策をまとめました。

環境

Unity:2022.3.26f1


まずは以下の設定を行います。

Timeline

まず、TimelineでVideoを扱えるようにするため、Package ManagerからDefault Playablesをインポートします。

Default Playables - Unity Asset Store

これにより、Video Script Playable Trackが使用できるようになります。「New Add Track」を選び新しいトラックをTimelineに登録します。

次に、右クリックで「Add From Video Player」を選択して、作成したVideo Playerを追加します。

最後に、InspectorでClip Timingを動画の長さに合わせて調整します。

スクリーンショット 2024-09-22 192114.png

VideoPlayer

Render Mode:Camera Near Plane
Camera:MainCamera

PlayableDirector

UpdateMethod:Manual
Play On Awake:False


設定ができたらTimelineを操作するスクリプトを書いていきます。

マニュアル操作になったPlayableDirectorへVideoPlayerの時間を入れてTimelineの時間を設定し、Evaluateを呼ぶことでTimelineを進めます。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Video;

public class TimelineController : MonoBehaviour
{
    private PlayableDirector playableDirector;
    private VideoPlayer videoPlayer;

    void Start()
    {
        playableDirector = GetComponent<PlayableDirector>();

        videoPlayer = GetComponent<VideoPlayer>();
        videoPlayer.playOnAwake = false;
    }

    void Update()
    {
        playableDirector.time = videoPlayer.clockTime;
        playableDirector.Evaluate();
    }

    public void VideoStart()
    {
        videoPlayer.frame = 0;
        videoPlayer.Play();
    }
    public void VideoPause()
    {
        videoPlayer.Pause();
    }
}

これでVideoPlayerに合わせTimelineが動くようになりましたが、
Timelineに置いたSignal Emitterが反応しないことに気が付きました。
どうやらUpdateMethodがマニュアルの場合はイベントが呼ばれないようです。


調べているとこちらのページにたどり着きました。

Packages/Timeline/Runtime/Playables/TimeNotificationBehaviour.cs

TimeNotificationBehaviour.cs
if (info.evaluationType == FrameData.EvaluationType.Evaluate)
{
    return;
}

どうやらこの部分の処理をコメントアウトすればEvaluate()での呼び出しであってもSignal Emitterが動作するようです。
このくらいであれば今回は影響がなさそうなので変更してしまいましょう。

ただしこのファイルはLibrary/PackageCache内にあり、ここのファイルを書き換えても気が付いたら書き換え前の状態に戻されてしまいます。

そこで、Library/PackageCachecom.unity.timeline@バージョン番号のディレクトリを\Packages内にコピーします。末尾の@バージョン番号は削除しておきます。
Package Managerで確認してCustomとついていればうまくいっています。
これでファイルの書き換えが維持されるようになりました。

無事、Signal Emitterが反応するようになったかと思います。:tada:

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?