当前位置:网站首页>Unity TimeLine 数据绑定
Unity TimeLine 数据绑定
2022-06-30 02:26:00 【依旧im】
恢复丢失的timeline绑定数据

在使用Timline的过程中 经常会发生 绑定的信息丢失了的情况。一般交付给我们的资源是美术制作好的timeline 动画 我们并不知道 绑定的节点对应物体。所以非常有必要。做一个绑定数据的记录工具。而且我们也需要对资源打包处理 ,在把资源做成AB包时 ,场景中的绑定信息也会丢失。这时就需要我们要动态的加载绑定信息。上代码。
TimeLineWinEditor :
主要负责创建 记录文件的。代码比较简单。直接看就行了。
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;
public class TimeLineWinEditor : EditorWindow
{
public static PlayableDirector playableDirector;
void OnGUI()
{
playableDirector = EditorGUILayout.ObjectField(playableDirector, typeof(PlayableDirector), true) as PlayableDirector;
if (GUILayout.Button("创建TimeLine记忆文件"))
{
Fork();
}
if (GUILayout.Button("读取TimeLine记忆文件"))
{
Restore();
}
}
//[MenuItem("TimelineTools/存储timeline绑定 %_i")]
private static void Fork()
{
List<string> bindingnames_Game;
List<string> bindingnames_Editor;
bindingnames_Editor = new List<string>();
bindingnames_Game = new List<string>();
//获取timelineAsset中所有轨道的迭代器
var bindings = playableDirector.playableAsset.outputs.GetEnumerator();
//复制轨道中的对象名称
while (bindings.MoveNext())
{
//获取当前轨道的绑定键
Object sourceObject = bindings.Current.sourceObject;
string bindingname_Editor;
string bindingname_Game;
//根据绑定键获取当前轨道绑定物体的名称
if (sourceObject != null)
{
if (playableDirector.GetGenericBinding(sourceObject))
{
Object obj1 = playableDirector.GetGenericBinding(sourceObject);
GameObject go = obj1 as GameObject;
if (go == null)
{
Animator animaotr = obj1 as Animator;
if (animaotr == null)
{
AudioSource audioSource = obj1 as AudioSource;
go = audioSource.gameObject;
}
else
{
go = animaotr.gameObject;
}
}
List<string> gameObjectNames = new List<string>();
while (go && go.name != null && go.name != "Point light")
{
gameObjectNames.Add(go.name);
if (go.transform.parent != null)
{
go = go.gameObject.transform.parent.gameObject;
}
else
{
go = null;
}
}
gameObjectNames.RemoveAt(gameObjectNames.Count - 1);
gameObjectNames.Reverse();
string path1 = null;
foreach (string str in gameObjectNames)
{
path1 += str;
path1 += "/";
}
if (path1 != null)
{
if (path1.Length > 0)
{
path1 = path1.Substring(0, path1.Length - 1);
}
}
Debug.Log(path1);
bindingname_Editor = playableDirector.GetGenericBinding(sourceObject).name;
bindingname_Game = path1;
}
else
{
bindingname_Editor = "";
bindingname_Game = "";
Debug.Log(sourceObject + "null");
}
if (!string.IsNullOrEmpty(bindingname_Game))
{
bindingnames_Game.Add(bindingname_Game);
}
if (!string.IsNullOrEmpty(bindingname_Editor))
{
bindingnames_Editor.Add(bindingname_Editor);
}
}
}
string path0 = string.Format("Assets/Resources/BindingAssets/{0}.asset", playableDirector.playableAsset.name);
//如果已经存在有binding的绑定,则决定是否替换或者保留
if (File.Exists(path0))
{
if (EditorUtility.DisplayDialog("注意", "替换原来的binding?", "是", "否"))
{
File.Delete(path0);
}
else
return;
}
//实例化类
BindingAsset bindingAsset = ScriptableObject.CreateInstance<BindingAsset>();
//赋初值
bindingAsset.playableName_Game = new string[bindingnames_Game.Count];
bindingAsset.playableName_Editor = new string[bindingnames_Editor.Count];
for (int i = 0; i < bindingnames_Game.Count; i++)
{
bindingAsset.playableName_Game[i] = bindingnames_Game[i];
}
for (int i = 0; i < bindingnames_Editor.Count; i++)
{
bindingAsset.playableName_Editor[i] = bindingnames_Editor[i];
}
//如果实例化为空,返回
if (!bindingAsset)
{
Debug.LogWarning("bindingAsset not found");
return;
}
//自定义资源保存路径
string path = Application.dataPath + "/Resources/BindingAssets";
//如果项目不包含该路径,创建一个
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
path = string.Format("Assets/Resources/BindingAssets/{0}.asset", playableDirector.playableAsset.name);
AssetDatabase.CreateAsset(bindingAsset, path);
}
private static void Restore()
{
string path = string.Format("Assets/Resources/BindingAssets/{0}.asset", playableDirector.playableAsset.name);
if (!File.Exists(path))
return;
BindingAsset bindingAsset = AssetDatabase.LoadAssetAtPath<BindingAsset>(path);
//获取timelineAsset中所有轨道的迭代器
var bindings = playableDirector.playableAsset.outputs.GetEnumerator();
int i = 0;
//根据对象名称恢复timeline的轨道
while (bindings.MoveNext())
{
//获取当前轨道的绑定键
Object sourceObject = bindings.Current.sourceObject;
if (sourceObject != null)
{
//通过名称找到需要绑定的物体
GameObject gameObject = FindObject2(bindingAsset.playableName_Editor[i]);
//通过绑定键和绑定物体的键值对,绑定Binding信息
playableDirector.SetGenericBinding(sourceObject, gameObject);
i++;
}
}
}
private static GameObject FindObject2(string name)
{
foreach (GameObject go in Resources.FindObjectsOfTypeAll(typeof(GameObject)))
{
if (!EditorUtility.IsPersistent(go.transform.root.gameObject) && !(go.hideFlags == HideFlags.NotEditable || go.hideFlags == HideFlags.HideAndDontSave))
{
if (go.name == name)
return go;
}
}
return null;
}
}BindingAsset
记录信息的配置文件
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "BindingAsset", fileName = "bindingAsset", order = 2)]
public class BindingAsset : ScriptableObject
{
public string[] playableName_Editor;
public string[] playableName_Game;
}AutoBindTimeLine
运行时自动绑定Timeline数据
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Playables;
public class AutoBindTimeLine : MonoBehaviour
{
public static AutoBindTimeLine instance;
public delegate void BindTimeLine(PlayableDirector playable);
public event BindTimeLine mBindTimeLine;
public PlayableDirector mPlayableDirector;
private void Awake()
{
instance = this;
}
// Start is called before the first frame update
void Start()
{
mBindTimeLine += AutoBindTimeLine_onBindTimeLine;
}
public void OnBindTimeLine(PlayableDirector mPlayableDirector)
{
if (mBindTimeLine != null)
{
mBindTimeLine?.Invoke(mPlayableDirector);
}
}
private void AutoBindTimeLine_onBindTimeLine(PlayableDirector playable)
{
string path = string.Format("Assets/Resources/BindingAssets/{0}.asset", playable.playableAsset.name);
if (!File.Exists(path))
return;
BindingAsset bindingAsset = Resources.Load<BindingAsset>("BindingAssets/" + playable.playableAsset.name);
//获取timelineAsset中所有轨道的迭代器
var bindings = playable.playableAsset.outputs.GetEnumerator();
int i = 0;
//根据对象名称恢复timeline的轨道
while (bindings.MoveNext())
{
Debug.Log(i);
//获取当前轨道的绑定键
Object sourceObject = bindings.Current.sourceObject;
if (sourceObject != null)
{
Debug.Log(bindingAsset.playableName_Game[i]);
GameObject gameObject = transform.Find(bindingAsset.playableName_Game[i]).gameObject;
//通过绑定键和绑定物体的键值对,绑定Binding信息
playable.SetGenericBinding(sourceObject, gameObject);
i++;
}
}
}
}
我们的脚本AutoBindTimeLine 要挂在一个父节点上面才能find到下面的子物体。

边栏推荐
猜你喜欢

2.< tag-动态规划和0-1背包问题>lt.416. 分割等和子集 + lt.1049. 最后一块石头的重量 II

什么是证书透明度CT?如何查询CT logs证书日志?

速看 2021-2022年23项重大网络犯罪统计数据

What is an X.509 certificate? 10. 509 certificate working principle and application?

重看《Redis设计与实现》后记录几个要点

Knowledge payment cannot escape the essence of "anxiety"

Seven common errors of SSL certificate and their solutions

Tencent released the first Office Photo 23 years ago. It's so chronological

SQL injection -day17

IBM websphere通道联通搭建和测试
随机推荐
新考纲下的PMP考试有多难?全面解析
DHU programming exercise
学术汇报(academic presentation)/PPT应该怎么做?
FDA mail security solution
CA数字证书包含哪些文件?如何查看SSL证书信息?
Merge sort
dhu编程练习
打造创客教育中精湛技艺
冒泡排序
DDoS threat situation gets worse
26. common interview questions of algorithm
Traffic, but no sales? 6 steps to increase website sales
Matlab code running tutorial (how to run the downloaded code)
Day_ 19 multithreading Basics
Weekly recommended short video: why is the theory correct but can not get the expected results?
dhu编程练习
Créer des compétences exquises dans l'éducation des créateurs
希尔排序
DigiCert Smart Seal是什么?
網上炒股安全麼?炒股需要開戶嗎?