Unity TimeLine自定义轨道(实践)
实践内容:实现歌词效果
行为脚本
public class SingingBehaviour : PlayableBehaviour
{
public string text;
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
var textControl = playerData as TextControl;
var progress = playable.GetTime() / playable.GetDuration();
textControl.UpdateText(text,(float)progress);
}
}
片段脚本
public class SingingClip : PlayableAsset, ITimelineClipAsset
{
private readonly SingingBehaviour _singingBehaviour = new SingingBehaviour();
public string text;
public override Playable CreatePlayable(PlayableGraph graph, GameObject owner)
{
var playable = ScriptPlayable<SingingBehaviour>.Create(graph, _singingBehaviour);
var clone = playable.GetBehaviour();
clone.text = text;
return playable;
}
public ClipCaps clipCaps => ClipCaps.None;
}
轨道脚本
[TrackColor(0.5f,0.4f,0.4f)]
[TrackClipType(typeof(SingingClip))]
[TrackBindingType(typeof(TextControl))]
public class SingingTrack : PlayableTrack
{
public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
{
return ScriptPlayable<SingingMixerBehaviour>.Create(graph, inputCount);
}
}
Mixer脚本(处理动画片段权重)
public class SingingMixerBehaviour : PlayableBehaviour
{
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
var textControl = playerData as TextControl;
var count = playable.GetInputCount();
var isEmpty = true;
for (var i = 0; i < count; i++)
{
var inputWeight = playable.GetInputWeight(i);
if (inputWeight > 0f)
{
isEmpty = false;
}
}
if (isEmpty)
{
textControl.UpdateText("",0f);
}
}
}
UI显示脚本
public class TextControl : MonoBehaviour
{
[SerializeField] private TextMeshProUGUI backTextMeshPro;
[SerializeField] private TextMeshProUGUI forwardTextMeshPro;
[SerializeField] private RectMask2D rectMask2D;
public void UpdateText(string text, float progress)
{
backTextMeshPro.text = text;
forwardTextMeshPro.text = text;
var x = forwardTextMeshPro.preferredWidth * progress;
rectMask2D.rectTransform.sizeDelta = new Vector2(x, forwardTextMeshPro.rectTransform.sizeDelta.y);
}
}
|