需求:同一场景中点击不同按钮播放不同的timeline
视频:https://www.bilibili.com/video/BV135411x7pp/
包括3个代码:
1.ModelBase_test.cs–定义timeline中的物体并进行查找;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ModelBase_test : MonoBehaviour
{
public GameObject worker_stand;
public GameObject worker_pufu;
private void Awake()
{
worker_stand = GameObject.FindGameObjectWithTag("worker_stand");
worker_pufu = GameObject.FindGameObjectWithTag("worker_pufu");
}
}
2.Timeline_manager_test.cs–管理加载timeline,点击按钮传值并播放不同的timeline;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
public class Timeline_manager_test : MonoBehaviour
{
private PlayableDirector director = null;
private TimelineUnit helper = null;
private ModelBase_test modelbase;
private void Awake()
{
director = GetComponent<PlayableDirector>();
if (director == null) {
director = gameObject.AddComponent<PlayableDirector>();
}
helper = new TimelineUnit();
helper.Init("tl",director);//存放制作好的timeline
modelbase = GameObject.Find("Directional Light").GetComponent<ModelBase_test>();
}
void Start()
{
}
public void Changetimeline(string timelinename) {
if (timelinename == "tl1")
{
helper.Switch(timelinename);
helper.SetBinding("Animation Track", modelbase.worker_stand);
helper.SetBinding("Animation Track1", modelbase.worker_stand);
helper.Play();
}
else if (timelinename == "tl2") {
helper.Switch(timelinename);
helper.SetBinding("Animation Track", modelbase.worker_pufu);
helper.SetBinding("Animation Track1", modelbase.worker_pufu);
helper.Play();
}
}
// Start is called before the first frame update
// Update is called once per frame
void Update()
{
}
}
3.TimelineUnit.cs–timeline的控制文件
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;
public class TimelineUnit
{
public string name;
public PlayableDirector director;
public PlayableAsset asset;
public Dictionary<string, PlayableBinding> bindings;
public Dictionary<string, Dictionary<string, PlayableAsset>> clips;
public Dictionary<string, PlayableAsset> playables;
public void Init(string path, PlayableDirector director)
{
this.name = path; // director标签
this.director = director; // 获取当前组件
playables = new Dictionary<string, PlayableAsset>();
InitPlayables(path); // 获得所有的动画
}
public void Switch(string assetName)
{
if (!playables.TryGetValue(assetName, out this.asset))
{
Debug.LogError("No Asset exist!");
return;
}
director.playableAsset = asset; // 导演Manager
bindings = new Dictionary<string, PlayableBinding>(); // PlayableAsset下的所有binding
clips = new Dictionary<string, Dictionary<string, PlayableAsset>>(); // binding里的所有clip
foreach (var o in asset.outputs) // 每一个binding,其实就是trackasset和需要动画的模型之间的链接关系
{
var trackname = o.streamName;
bindings.Add(trackname, o); // 每一个binding的名字和binding绑定
var track = o.sourceObject as TrackAsset; // 每个binding下的对象为track
if (track == null) continue;
var clipList = track.GetClips(); // 获得每一个track下的所有动画片段
foreach (var c in clipList) // 存入clips
{
if (!clips.ContainsKey(trackname))
{
clips[trackname] = new Dictionary<string, PlayableAsset>();
}
var name2clips = clips[trackname];
if (!name2clips.ContainsKey(c.displayName))
{
name2clips.Add(c.displayName, c.asset as PlayableAsset);
}
}
}
}
// 清空数据
public void Remove()
{
bindings.Clear();
clips.Clear();
}
// 动画和模型进行绑定
public void SetBinding(string trackName, Object o)
{
director.SetGenericBinding(bindings[trackName].sourceObject, o);
}
// 获得动画轨道
public T GetTrack<T>(string trackName) where T : TrackAsset
{
return bindings[trackName].sourceObject as T;
}
// 获得动画片段
public T GetClip<T>(string trackName, string clipName) where T : PlayableAsset
{
if (clips.ContainsKey(trackName))
{
var track = clips[trackName];
if (track.ContainsKey(clipName))
{
return track[clipName] as T;
}
else
{
Debug.LogError("GetClip Error, Track does not contain clip, trackName: " + trackName + ", clipName: " + clipName);
}
}
else
{
Debug.LogError("GetClip Error, Track does not contain clip, trackName: " + trackName + ", clipName: " + clipName);
}
return null;
}
// 读入所有动画资源
private void InitPlayables(string path)
{
PlayableAsset[] o = Resources.LoadAll<PlayableAsset>(path + "/");
foreach (var asset in o)
{
playables.Add(asset.ToString().Replace(" (UnityEngine.Timeline.TimelineAsset)", ""), asset);
Debug.Log(asset.ToString());
}
}
// 播放动画
public void Play()
{
director.Play();
}
public void pause()
{
director.Pause();
}
public void Stop()
{
director.Stop();
}
public void Resume()
{
director.Resume();
}
}
实现效果如下:点击run按钮上面的人开始跑,点击pufu按钮下面的人开始爬行