模型提供的动画是一个模型下一个动画
然后懒人不想手动拖动模型变成预制体在一个一个拖入Timeline中 于是就写了一个编辑器工具 直接看代码吧
using UnityEditor;
using UnityEngine;
using UnityEngine.Timeline;
using System.IO;
using UnityEngine.Playables;
using System.Collections.Generic;
public class Test : EditorWindow
{
string m_PartID;
private List<AnimationClip> animationsList = new List<AnimationClip>();
private List<GameObject> prefabList = new List<GameObject>();
private GameObject parentGame;
private PlayableDirector playableDir;
/// <summary>
/// 创建timelineassets的路径
/// </summary>
public string timelineplayablePath = "Assets/playable/TimelinePlayable/TimelineGame.playable";
/// <summary>
/// 所需的Fbx的路径
/// </summary>
public string fbxPath = "Assets/model/BMS";
private string groupTrack = "first";
[MenuItem("Tools/TimelineGenerator")]
public static void Init()
{
GetWindow<Test>().Show();
}
public void OnGUI()
{
if (GUILayout.Button("GenerateTimeline"))
Generate();
GUILayout.EndVertical();
}
void Generate()
{
animationsList.Clear();
prefabList.Clear();
var asset = TimelineAsset.CreateInstance<TimelineAsset>();
if (AssetDatabase.IsValidFolder("Assets/Playable"))
{
//AssetDatabase.CreateFolder("Assets", "Test/test.playable");
AssetDatabase.CreateAsset(asset, timelineplayablePath);
}
else
{
AssetDatabase.CreateFolder("Assets", "Playable");
AssetDatabase.CreateAsset(asset, timelineplayablePath);
}
parentGame = new GameObject("TimelineGame");
parentGame.AddComponent<PlayableDirector>();
parentGame.AddComponent<Animator>();
playableDir = parentGame.GetComponent<PlayableDirector>();
playableDir.playableAsset = asset;
GroupTrack group = asset.CreateTrack<GroupTrack>(null, groupTrack);
getpath(fbxPath);
double time = 0;
for (int i = 0; i < prefabList.Count; i++)
{
AnimationTrack track = asset.CreateTrack<AnimationTrack>(group, prefabList[i].name);
//物体在轨道上的位置(默认为vector.zero)要与原位置一样 不然会出现偏移
track.trackOffset = TrackOffset.ApplySceneOffsets;
//track.position = prefabList[i].transform.position;
//track.rotation = prefabList[i].transform.rotation;
track.CreateClip(animationsList[i]);
foreach (TimelineClip item in track.GetClips())
{
item.start = time;
//item.timeScale = 2;//默认为1倍播放速度
time += item.duration;
//time += item.duration / item.timeScale;
break;
}
}
foreach (var bind in playableDir.playableAsset.outputs)
{
if (!bindingDict.ContainsKey(bind.streamName))
{
bindingDict.Add(bind.streamName, bind);
}
}
for (int i = 0; i < prefabList.Count; i++)
{
SetTrackDynamic(prefabList[i].name, prefabList[i]);
}
AssetDatabase.SaveAssets();
EditorGUIUtility.PingObject(parentGame);
Selection.activeGameObject = parentGame;
}
private readonly Dictionary<string, PlayableBinding> bindingDict = new Dictionary<string, PlayableBinding>();
/// <summary>
/// 添加gameobject在时间线的绑定
/// </summary>
/// <param name="trackName"></param>
/// <param name="gameObject"></param>
public void SetTrackDynamic(string trackName, GameObject gameObject)
{
if (bindingDict.TryGetValue(trackName, out PlayableBinding pb))
{
playableDir.SetGenericBinding(pb.sourceObject, gameObject);
}
}
/// <summary>
/// 利用系统路径 获取某路径下的fbx文件的路径
/// </summary>
/// <param name="exportPath"></param>
/// <returns></returns>
public void getpath(string exportPath)
{
//判断某个文件夹是否存在,不存在就创建
if (!Directory.Exists(exportPath))
{
Directory.CreateDirectory(exportPath);
}
//获取指定目录下的所有.FBX文件
string exefileName = "";
DirectoryInfo direction = new DirectoryInfo(exportPath);
//获取文件夹,exportPath是文件夹的路径
FileInfo[] files = direction.GetFiles("*", SearchOption.AllDirectories);
//*是获取这个文件夹下的所有文件,
for (int i = 0; i < files.Length; i++)
{
//判断文件的后缀
if (files[i].Name.EndsWith(".FBX"))
{
exefileName = files[i].FullName;
//系统路径修改为unity路径
exefileName = exefileName.Remove(0, exefileName.IndexOf("Assets"));
AnimLoad(exefileName);
}
}
}
/// <summary>
/// 获取fbxPath路径下的Clip文件和Instantiate一个物体到面板
/// </summary>
/// <param name="fbxPath"></param>
private void AnimLoad(string fbxPath)
{
///获取fbx下的指定文件
AnimationClip clip = AssetDatabase.LoadAssetAtPath(fbxPath, typeof(AnimationClip)) as AnimationClip;
GameObject game = Instantiate(AssetDatabase.LoadAssetAtPath(fbxPath, typeof(GameObject)) as GameObject, parentGame.transform);
if (clip != null && game != null)
{
prefabList.Add(game);
animationsList.Add(clip);
}
}
}