Please enable Javascript to view the contents

讓Unity的Timeline支援TextMeshPro進行文本變化

 ·  ☕ 3 分钟  ·  👩🏿‍🚀 伊琉沙 AKA 哇咔咔

17年在台灣參加Unity工作坊的一個項目——Hover Race,曾使用preview版本的TMP,記得當時可以直接把TMP Text拖到Timeline就能建立TMP的Track與Clip,並直接建立文本變換。最近有個項目需要使用這個功能,多年沒碰Timeline(DoTween使用慣了就懶)發現這個功能消失了,看到知乎的這篇Timeline中让你事半功倍的工具链才知道有些功能被整合自獨立的Asset了,於是重新研究了一下,並再次實現這個功能。
如果你的專題也有Timeline變換TMP文本的需求就看下去,同時也能一同學習客製化Playable
TMP Text Switcher Track

開發環境

  • Unity 2018.4.20f1
  • TextMesh Pro 1.4.1

下載Default Playables

先到Asset Store下載最新版的Default Playables,這是Unity官方自行整合的Playable功能包。
Text Switcher Track
導入後刷新Timeline窗口,可以發現增加了一堆功能,而我們要使用的文本轉換也有,可惜地是只支援UGUI Text,不過可以在Asset中的DefaultPlayables中找到Text Switcher Track功能的源代碼,看起來只要將裡面的UGUI Text全部換成TMP Text就能實作TMP Text Switcher Track。

實作TMP Text Switcher Track

Text Switcher Track Folder
在DefaultPlayables的TextSwitcher目錄中包含五個腳本,以下直接複製一份TextSwitcher到根目錄改名為TMPTextSwitcher
接下來就要改裡面的代碼。

TMPTextSwitcherBehaviour

TMPTextSwitcherBehaviour.cs中只要改類名稱即可。
這部分是實作TMP Text能被修改的變量,有需求可自行增加。

1
2
3
4
5
6
7
[Serializable]
public class TMPTextSwitcherBehaviour : PlayableBehaviour
{
    public Color color = Color.white;
    public int fontSize = 14;
    public string text;
}

TMPSwitcherDrawer

在Editor資料夾下的TMPSwitcherDrawer.cs主要是描繪Inspector的顯示界面,內容對應TMPTextSwitcherBehaviour中需要修改的變量,需要修改的地方有兩處:

  • CustomPropertyDrawer標籤的指定型別
1
[CustomPropertyDrawer(typeof(TMPTextSwitcherBehaviour))]
  • 類名稱
1
2
3
4
public class TMPSwitcherDrawer : PropertyDrawer
{
    ...
}

TMPTextSwitcherClip

TMPTextSwitcherClip.cs的修改有三處:

  • 類名稱
1
2
3
4
5
[Serializable]
public class TMPTextSwitcherClip : PlayableAsset, ITimelineClipAsset
{
    ...
}
  • template的宣告與初始
1
2
3
4
5
public class TMPTextSwitcherClip : PlayableAsset, ITimelineClipAsset
{
    public TMPTextSwitcherBehaviour template = new TMPTextSwitcherBehaviour ();
    ...
}
  • playable的建立方法
1
2
3
4
5
6
7
8
9
public class TMPTextSwitcherClip : PlayableAsset, ITimelineClipAsset
{
    ...
    public override Playable CreatePlayable (PlayableGraph graph, GameObject owner)
    {
        var playable = ScriptPlayable<TMPTextSwitcherBehaviour>.Create (graph, template);
        return playable;
    }
}

TMPTextSwitcherMixerBehaviour

  • 類名稱
1
2
3
4
public class TMPTextSwitcherMixerBehaviour : PlayableBehaviour
{
    ...
}
  • inputPlayable的宣告與初始化
  • input的宣告
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
    public override void ProcessFrame(Playable playable, FrameData info, object playerData)
    {
        ...
        for (int i = 0; i < inputCount; i++)
        {
            ...
            ScriptPlayable<TMPTextSwitcherBehaviour> inputPlayable = (ScriptPlayable<TMPTextSwitcherBehaviour>)playable.GetInput(i);
            TMPTextSwitcherBehaviour input = inputPlayable.GetBehaviour ();
            ...
        }
        ...
    }
  • 引入TMPro
  • m_DefaultFontSize的型別改為float
  • m_TrackBinding的型別改為TextMeshProUGUI
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
// using UnityEngine.UI;
using TMPro;

public class TMPTextSwitcherMixerBehaviour : PlayableBehaviour
{
    ...
    float m_DefaultFontSize;
    ...
    TextMeshProUGUI m_TrackBinding;
    ...

    public override void ProcessFrame(Playable playable, FrameData info, object playerData)
    {
        m_TrackBinding = playerData as TextMeshProUGUI;
        ...
    }
}

TextSwitcherTrack

TextSwitcherTrack.cs

  • 引入TMPro
  • TrackClipType標籤的指定型別為TMPTextSwitcherClip
  • TrackBindingType標籤的指定型別為TextMeshProUGUI
  • 類名稱
1
2
3
4
5
6
7
8
9
// using UnityEngine.UI;
using TMPro;

[TrackClipType(typeof(TMPTextSwitcherClip))]
[TrackBindingType(typeof(TextMeshProUGUI))]
public class TMPTextSwitcherTrack : TrackAsset
{
    ...
}
  • CreateTrackMixerde的建立方法
1
2
3
4
5
6
7
8
public class TMPTextSwitcherTrack : TrackAsset
{
    public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
    {
        return ScriptPlayable<TMPTextSwitcherMixerBehaviour>.Create (graph, inputCount);
    }
    ...
}
  • trackBinding的型別修改為TextMeshProUGUI
  • driver.AddFromName方法的型別
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
public class TMPTextSwitcherTrack : TrackAsset
{
    ...
    public override void GatherProperties (PlayableDirector director, IPropertyCollector driver)
    {
#if UNITY_EDITOR
        TextMeshProUGUI trackBinding = director.GetGenericBinding(this) as TextMeshProUGUI;
        ...
        while (iterator.NextVisible(true))
        {
            ...
            driver.AddFromName<TextMeshProUGUI>(trackBinding.gameObject, iterator.propertyPath);
        }
#endif
        ...
    }
}
分享

伊琉沙 AKA 哇咔咔
作者
伊琉沙 AKA 哇咔咔
遊戲開發者 / 密室機關師