タイムラインで動画に字幕を付ける #1では、タイムラインで字幕の表示位置を変えられなかったので、新しくPlayableAssetとPlayableBehaviourを作ってみました。
2つのスクリプトを作る
まず、Projectウィンドウで右クリックからPlayableAssetとPlayableBehaviourを新規作成します。
これらを使って、自作のトラックとクリップを作れます。PlayableBehaviourでは、字幕の表示に必要なテキストや表示位置などの値をセットできるようにして、OnBehaviourPlayメソッドに、クリップでの処理内容を書きました。
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Playables;
// A behaviour that is attached to a playable
public class NewPlayableBehaviour : PlayableBehaviour
{
public Text text; // Textコンポーネント
public Color color; // 色
public int fontSize; // 文字サイズ
public string content; // テキストの内容
public Vector3 position; // 表示位置
// Called when the owning graph starts playing
public override void OnGraphStart(Playable playable)
{
}
// Called when the owning graph stops playing
public override void OnGraphStop(Playable playable)
{
}
// Called when the state of the playable is set to Play
public override void OnBehaviourPlay(Playable playable, FrameData info)
{
// テキストの色を変える
text.color = color;
// フォントサイズを変える
text.fontSize = fontSize;
// 表示内容を変える
text.text = content;
// 表示位置を変える
text.rectTransform.localPosition = position;
}
// Called when the state of the playable is set to Paused
public override void OnBehaviourPause(Playable playable, FrameData info)
{
// テキストを空にする
text.text = "";
}
// Called each frame while the state is set to Play
public override void PrepareFrame(Playable playable, FrameData info)
{
}
}
OnBehaviourPlayメソッドは、シークバーがクリップに乗ったときに一度だけ呼ばれるようです。クリップが終了したときにはOnBehaviourPauseメソッドが呼ばれるので、ここでテキストを空にしています。
PlayableAssetでは、インスペクタで値をセットできるようにして、上のPlayableBehaviourのインスタンスにそれらを渡します。
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Playables;
[System.Serializable]
public class NewPlayableAsset : PlayableAsset
{
public ExposedReference text;
public Color color;
public int fontSize;
public string content;
public Vector3 position;
// Factory method that generates a playable based on this asset
public override Playable CreatePlayable(PlayableGraph graph, GameObject go)
{
// PlayableBehaviourのインスタンス
var behaviour = new NewPlayableBehaviour();
// インスペクタで設定した値を入れる
behaviour.color = color;
behaviour.fontSize = fontSize;
behaviour.content = content;
behaviour.position = position;
// シーンのテキストを入れる
behaviour.text = text.Resolve(graph.GetResolver());
return ScriptPlayable<NewPlayableBehaviour>.Create(graph, behaviour);
}
}
シーンのオブジェクトはそのまま設定できないので、シーンオブジェクトへの参照を作れるジェネリック型のExposedReferenceを使います。PlayableBehaviourのインスタンスにテキストコンポーネントを渡すときは、ExposedReference.Resolveメソッドを呼んでいます。
Playable Trackを作る
2つのスクリプトができたら、タイムラインの左側の何もないところで右クリックして、Playable Trackを作ります。
さらにこのトラックを右クリックして、今作ったPlayable Assetを追加します。
シークバーがこのクリップ上にあるときに字幕が表示されます。このクリップやクリップの端をドラッグして、字幕の表示タイミングや長さを変えられます。
クリップを選択すると、インスペクタで字幕の文字色やサイズ、内容や表示位置を変えられます。
また、シーンのテキストオブジェクトをドラッグアンドドロップして、テキストコンポーネントを設定します。
クリップを選択中にCtrl + Dでそのクリップを複製できます。それぞれに別々の値を設定できます。
参考:https://simplestar-tech.hatenablog.com/entry/2018/09/23/141755
https://docs.unity3d.com/ScriptReference/ExposedReference_1.html