当前位置:网站首页>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到下面的子物体。

边栏推荐
- What is certificate transparency CT? How to query CT logs certificate logs?
- DDoS "fire drill" service urges companies to prepare
- SSL证书格式转化的两种方法
- DDoS extortion attacks: what you need to know
- vs实现快速替换功能
- dhu编程练习
- 速看 2021-2022年23项重大网络犯罪统计数据
- Several key points recorded after reviewing redis design and Implementation
- The odoo15 page jumps directly to the editing status
- Implement vs to run only one source file at a time
猜你喜欢

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

How to create a CSR (certificate signing request) file?

Traffic, but no sales? 6 steps to increase website sales

如何制作CSR(Certificate Signing Request)文件?

Weekly recommended short video: why is the theory correct but can not get the expected results?

打造創客教育中精湛技藝

Shell Sort

After the blueprint node of ue5 is copied to UE4, all connections and attribute values are lost
![[Galaxy Kirin V10] [desktop] Firefox browser settings home page does not take effect](/img/96/e3afb2b9683cce7645afd483cc0844.png)
[Galaxy Kirin V10] [desktop] Firefox browser settings home page does not take effect

SSL证书七大常见错误及解决方法
随机推荐
Day_ 19 multithreading Basics
PMP考生如何应对新考纲?看过来!
PEM_ read_ bio_ Privatekey() returns null only in ECB mode - PEM_ read_ bio_ PrivateKey() returns NULL in ECB mode only
Playful palette: an interactive parametric color mixer for artists
AutoJS代码能加密吗?YES,AutoJS加密技巧展示
Large scale DDoS attacks and simulated DDoS tests against VoIP providers
dhu编程练习
dhu编程练习
Blue Bridge Cup stm32g431 - three lines of code for keys (long press, short press, click, double click)
什么是X.509证书?X.509证书工作原理及应用?
Heap sort
Select sort
Recommendations for agileplm database parameter optimization
DHU programming exercise
Widget uses setimageviewbitmap method to set bug analysis
FDA ESG regulation: digital certificate must be used to ensure communication security
[论]【DSTG】Dynamic SpatiotemporalGraph Convolutional Neural Networks for Traffic Data Imputation
[on] [DSTG] dynamic spatiotemporalgraph revolutionary neural networks for traffic data impact
堆排序
CTF introductory learning (WEB direction)