Unity

发布时间:2021-07-30 13:26:00

Timeline中,可以通过脚本扩展自定义的剪辑,轨道,混合轨道,Inspector属性显示器。


我这里参考了官方的 Default Playables的一个节点扩展方式,它也提供了一个辅助工具,非常方便,基本上我们只管处理轨道、混合轨道处理的逻辑就好了,其他的只需要鼠标点点点就可以创建好你想要的效果。


当然,如果辅助工具某些功能不满足你想要的,你也可以自己编辑脚本来扩展。


那下面我们就用这个辅助工具来创建自定义内容吧。


工具面板

首先打开辅助工具的向导面板


Playable Name

首先是我们的剪辑名字


如:TestingTRS_Scale


那么工具会帮助我们自动创建以下几个类:


XXXXBehaviour : PlayableBehaviour - 普通剪辑逻辑要处理的内容,逻辑也可以写到 混合剪辑逻辑XXXXClip : PlayableAsset, ITimelineClipAsset - 剪辑资源要保存的数据内容XXXXMixerBehaviour : PlayableBehaviour - 混合剪辑逻辑要处理的内容,对混合数据的收集,或是处理,其实也可以只在这里收集数据,然后传到 普通剪辑逻辑 里处理混合也是可以的。XXXXTrack : TrackAsset - 轨道资源要处理的内容,主要让轨道在处理混合时,应该用哪些逻辑类来处理混合。XXXXDrawer : PropertyDraw - 剪辑属性绘制器,主要处理在Timeline 的 Clips view中选中的剪辑,然后在Inspector窗口中显示的绘制内容。

这些类虽然是工具帮我们生成的。
但是我们也是可以自己手写的,只是用工具会更快而已,不用写太多的代码。


Standard Blend Playable

是否创建标准的可混合的Playable
选没选中,区别在于:


选中,Track Binding Type 可以选择: 可实例化,并继承自 UnityEngine.Component 的所有类。没选,Track Binding Type 可以选择:继承自 UnityEngine.Component 的所有类外,还可以选中GameObject,与null,的额外两种。

从代码中可以看出来:


if (isStandardBlendPlayable) // 选中 Standard Blend Playable
{
oldIndex = m_ComponentBindingTypeIndex;

m_ComponentBindingTypeIndex = EditorGUILayout.Popup (m_TrackBindingTypeContent, m_ComponentBindingTypeIndex, UsableType.GetGUIContentWithSortingArray (s_ComponentTypes)); // 使用的是集合:s_ComponentTypes
trackBinding = s_ComponentTypes[m_ComponentBindingTypeIndex];

EditorGUILayout.Space ();

defaultValuesComponent = EditorGUILayout.ObjectField (m_DefaultValuesComponentContent, defaultValuesComponent, trackBinding.type, true) as Component;
}
else // 没选
{
m_TrackBindingTypeIndex = EditorGUILayout.Popup(m_TrackBindingTypeContent, m_TrackBindingTypeIndex, UsableType.GetGUIContentWithSortingArray(s_TrackBindingTypes)); // 使用的是集合:s_TrackBindingTypes
trackBinding = s_TrackBindingTypes[m_TrackBindingTypeIndex];
}

可以看到分别使用了不一样的TrackBindingType的集合而已,那再去看看这两个集合的收集区别


Type[] componentTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()).Where(t => typeof(Component).IsAssignableFrom(t)).Where (t => t.IsPublic).ToArray();

List componentUsableTypesList = UsableType.GetUsableTypeArray(componentTypes).ToList();
componentUsableTypesList.Sort();
s_ComponentTypes = componentUsableTypesList.ToArray (); // Starndard Blend Playable == true是使用的TrackBindingType的集合

UsableType gameObjectUsableType = new UsableType(typeof(GameObject));
UsableType[] defaultUsableTypes = UsableType.GetUsableTypeArray(componentTypes, gameObjectUsableType);

List exposedRefTypeList = defaultUsableTypes.ToList ();
exposedRefTypeList.Sort();
s_ExposedReferenceTypes = exposedRefTypeList.ToArray();

UsableType noneType = new UsableType((Type)null);
s_TrackBindingTypes = UsableType.AmalgamateUsableTypes(s_ExposedReferenceTypes, noneType); // Starndard Blend Playable == false是使用的TrackBindingType的集合
// 所以我们可以看到,仅仅比s_ComponentTypes ,多了个:GameObject,与null类。

选中前的界面

当你选中了 Standard Blend Playable后,你会发现界面精简了很多。


选中后的界面


Track Binding Type

就是Track之接受处理的数据对象是什么类型的


Exposed References

因为Timeline中的变量不能直接暴露应用的类型变量。
所以专门独立出来一项,添加引用类型的变量,以与值类型的分开。
如果Standard Blend Playable选中的话,Exposed References不显示,就是不提供设置。
点击’Add按钮’,出现新的一个变量栏,然后你可以对变量默认的名字:newBehaviourVariable,重命名成你想要的,右边还有变量的类型选择。
点击’Remove按钮’,可删除对应的变量。


Behaviour Variables

行为逻辑类的变量


如果Standard Blend Playable选中的话,就叫:Standard Blend Playable Properties,叫法不一致而已。
点击’Add按钮’,出现新的一个变量栏,然后你可以对变量默认的名字:newBehaviourVariable,重命名成你想要的,右边还有变量的类型选择。
点击’Remove按钮’,可删除对应的变量。


Clip Caps

可理解为:剪辑的内置功能开始选项。


开启的功能,在Inspector中会显示一些该剪辑通用的属性项。


再脚本中定义如下:


public enum ClipCaps
{
All = -1,
None = 0,
Looping = 1,
Extrapolation = 2,
ClipIn = 4,
SpeedMultiplier = 8,
Blending = 16
}

ClipCaps的枚举简介
All 就是开始所有内置的剪辑功能。None 啥都不开启,只有 Clip Timing属性的Start,End,Duration可调整Looping 描述说的是,可以对剪辑内的可以循环播放,只要剪辑还处于播放中的话(目前这个没看到有什么用)Extrapolation 开启,并显示对剪辑编辑Clip Extrapolation的设置,可以对空白内容的外插模拟数据Clip In 开启,并提供可对剪辑的裁剪设置,一般Animation Clip才有用。自定义脚本我决定没啥用。SpeedMultiplier 开启,对剪辑的内容加速播放。一般Animation Clip才有用。Blending 开启后,可以对空白内容与剪辑内容的混合过渡处理。
Track Color

轨道的颜色



如果调整为红色,那么Timeline中的轨道左侧红色条,与剪辑下面的红色条,就是Track Color。


Create Drawer?

是否创建剪辑的Inspector属性绘制器


如下图的红色框中的,就是选中 Create Drawer后的结果。



选中 Create Drawer,对应编辑器代码:

using UnityEditor;
using UnityEngine;

[CustomPropertyDrawer(typeof(TestingTRS_ScaleBehaviour))]
public class TestingTRS_ScaleDrawer : PropertyDrawer
{
public override float GetPropertyHeight (SerializedProperty property, GUIContent label)
{
int fieldCount = 3;
return fieldCount * EditorGUIUtility.singleLineHeight;
}

public override void OnGUI (Rect position, SerializedProperty property, GUIContent label)
{
SerializedProperty scaleXProp = property.FindPropertyRelative("scaleX");
SerializedProperty scaleYProp = property.FindPropertyRelative("scaleY");
SerializedProperty scaleZProp = property.FindPropertyRelative("scaleZ");

Rect singleFieldRect = new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight);
EditorGUI.PropertyField(singleFieldRect, scaleXProp);

singleFieldRect.y += EditorGUIUtility.singleLineHeight;
EditorGUI.PropertyField(singleFieldRect, scaleYProp);

singleFieldRect.y += EditorGUIUtility.singleLineHeight;
EditorGUI.PropertyField(singleFieldRect, scaleZProp);
}
}


没选 Create Drawer,对应编辑器代码:

using UnityEditor;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.UI;

[CustomPropertyDrawer(typeof(TestingTRS_ScaleDrawer))]
public class TestingTRS_ScaleDrawer : PropertyDrawer
{
public override float GetPropertyHeight (SerializedProperty property, GUIContent label)
{
int fieldCount = 0;
return fieldCount * EditorGUIUtility.singleLineHeight;
}

public override void OnGUI (Rect position, SerializedProperty property, GUIContent label)
{

Rect singleFieldRect = new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight);
}
}


面板里的基本介绍得差不多了


下面说说,主要扩展混合剪辑的代码
介绍说明我都写注释里吧


主要看:// === add start ===// === add end ===之间的内容,其他都是生成的代码。


using System;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;

public class TestingTRS_ScaleMixerBehaviour : PlayableBehaviour
{
// === add start ===
// 一些辅助变量
private bool firstFrae = false; // 是否处理过第一帧的逻辑
private Vector3 srcScale = Vector3.one; // 轨道处理前的原始缩放值
private Transform trackBinding; // 这个就是我嗯Track Binding Type指定的类型变量
// === add end ===

// NOTE: This function is called at runtime and edit time. Keep that in mind when setting the values of properties.
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
trackBinding = playerData as Transform;

if (!trackBinding)
return;

// === add start ===
if (!firstFrae) // 没有处理过第一帧
{
firstFrae = true; // 处理过了,将标识打上
srcScale = trackBinding.localScale; // 记录轨道处理前的数据
}
// === add end ===

int inputCount = playable.GetInputCount ();

// === add start ===
float totalWeight = 0; // 总的混合权重
float blendX = 0; // scaleX的混合值
float blendY = 0; // scaleY的混合值
float blendZ = 0; // scaleZ的混合值
// === add end ===

for (int i = 0; i < inputCount; i++)
{
float inputWeight = playable.GetInputWeight(i);
ScriptPlayable inputPlayable = (ScriptPlayable)playable.GetInput(i);
TestingTRS_ScaleBehaviour input = inputPlayable.GetBehaviour ();
// Use the above variables to process each frame of this playable.
// === add start ===
totalWeight += inputWeight; // 累加混合权重
blendX += inputWeight * input.scaleX; // 根据权重值,将每一个剪辑的值都以混合权重值来做插值
blendY += inputWeight * input.scaleY;
blendZ += inputWeight * input.scaleZ;
// === add end ===
}

// === add start ===
trackBinding.localScale = new Vector3(blendX, blendY, blendZ); // 将混合后的权重设置到binding数据中
// === add end ===
}
// === add start ===
public override void OnPlayableDestroy(Playable playable) // 在剪辑销毁时恢复之前的缩放值
{
if (trackBinding != null && firstFrae)
{
firstFrae = false;
trackBinding.localScale = srcScale;
}
}
// === add end ===
}


创建Timeline,并运行效果
创建Timeline

选中TestTL对象,点击Timeline窗口中的Create按钮


添加轨道
先删除不必要的默认添加的:Animation轨道再添加我们刚刚新创建的TestingTRS_Scale轨道

设置Track Binding Data
设置轨道Binding的数据对象
因为我们的TestTRS_Scale接受的是Transform对象,Cube上有,我们就将它拖拽到轨道绑定的数据对象*伞

添加TestTRS_Scale剪辑,并设置剪辑数据
我们添加了剪辑并对剪辑存储的数scaleX,scaleY,scaleZ都设置为2并对剪辑的名字设置为:2,2,2就是代表scaleX,Y,Z都是2,方便Timeline上的剪辑维护


复制多几个剪辑,再调整数据
Ctrl+D,或是Ctrl+C,V,来复制剪辑调整剪辑的scaleX数据调整剪辑的显示名字,方便维护

先看看运行效果,很生硬的设置缩放值,后面添加混合会*滑很多


处理混合剪辑
手动调整Clip Timing中的 Ease In DurationEase Out Duration分别可以调整剪辑对空白内容的插值过渡在Clip Edit Mode为Mix时,调整剪辑之间的位置,让他们有重叠位置,就可以混合了(当然脚本首先要支持MixerBehaviour)

混合的说明我之前翻译过一篇官方手册教程,可以看看:Unity - Timeline 之 Blending clips(混合剪辑)


再运行看看混合效果


Code
TestingTRS_ScaleBehaviour.cs

using System;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;

[Serializable]
public class TestingTRS_ScaleBehaviour : PlayableBehaviour
{
public float scaleX;
public float scaleY;
public float scaleZ;
}


TestingTRS_ScaleClip.cs

using System;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;

[Serializable]
public class TestingTRS_ScaleClip : PlayableAsset, ITimelineClipAsset
{
public TestingTRS_ScaleBehaviour template = new TestingTRS_ScaleBehaviour ();

public ClipCaps clipCaps
{
get { return ClipCaps.Blending; }
}

public override Playable CreatePlayable (PlayableGraph graph, GameObject owner)
{
return ScriptPlayable.Create (graph, template);
}
}


TestingTRS_ScaleMixerBehaviour.cs

using System;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;

public class TestingTRS_ScaleMixerBehaviour : PlayableBehaviour
{
// === add start ===
// 一些辅助变量
private bool firstFrae = false; // 是否处理过第一帧的逻辑
private Vector3 srcScale = Vector3.one; // 轨道处理前的原始缩放值
private Transform trackBinding; // 这个就是我嗯Track Binding Type指定的类型变量
// === add end ===

// NOTE: This function is called at runtime and edit time. Keep that in mind when setting the values of properties.
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
trackBinding = playerData as Transform;

if (!trackBinding)
return;

// === add start ===
if (!firstFrae) // 没有处理过第一帧
{
firstFrae = true; // 处理过了,将标识打上
srcScale = trackBinding.localScale; // 记录轨道处理前的数据
}
// === add end ===

int inputCount = playable.GetInputCount ();

// === add start ===
float totalWeight = 0; // 总的混合权重
float blendX = 0; // scaleX的混合值
float blendY = 0; // scaleY的混合值
float blendZ = 0; // scaleZ的混合值
// === add end ===

for (int i = 0; i < inputCount; i++)
{
float inputWeight = playable.GetInputWeight(i);
ScriptPlayable inputPlayable = (ScriptPlayable)playable.GetInput(i);
TestingTRS_ScaleBehaviour input = inputPlayable.GetBehaviour ();
// Use the above variables to process each frame of this playable.
// === add start ===
totalWeight += inputWeight; // 累加混合权重
blendX += inputWeight * input.scaleX; // 根据权重值,将每一个剪辑的值都以混合权重值来做插值
blendY += inputWeight * input.scaleY;
blendZ += inputWeight * input.scaleZ;
// === add end ===
}

// === add start ===
trackBinding.localScale = new Vector3(blendX, blendY, blendZ); // 将混合后的权重设置到binding数据中
// === add end ===
}
// === add start ===
public override void OnPlayableDestroy(Playable playable) // 在剪辑销毁时恢复之前的缩放值
{
if (trackBinding != null && firstFrae)
{
firstFrae = false;
trackBinding.localScale = srcScale;
}
}
// === add end ===
}


TestingTRS_ScaleTrack.cs

using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;

[TrackColor(1f, 0f, 0.2057924f)]
[TrackClipType(typeof(TestingTRS_ScaleClip))]
[TrackBindingType(typeof(Transform))]
public class TestingTRS_ScaleTrack : TrackAsset
{
public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
{
return ScriptPlayable.Create (graph, inputCount);
}
}


TestingTRS_ScaleDrawer.cs(Editor文件夹下)

using UnityEditor;
using UnityEngine;

[CustomPropertyDrawer(typeof(TestingTRS_ScaleBehaviour))]
public class TestingTRS_ScaleDrawer : PropertyDrawer
{
public override float GetPropertyHeight (SerializedProperty property, GUIContent label)
{
int fieldCount = 3;
return fieldCount * EditorGUIUtility.singleLineHeight;
}

public override void OnGUI (Rect position, SerializedProperty property, GUIContent label)
{
SerializedProperty scaleXProp = property.FindPropertyRelative("scaleX");
SerializedProperty scaleYProp = property.FindPropertyRelative("scaleY");
SerializedProperty scaleZProp = property.FindPropertyRelative("scaleZ");

Rect singleFieldRect = new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight);
EditorGUI.PropertyField(singleFieldRect, scaleXProp);

singleFieldRect.y += EditorGUIUtility.singleLineHeight;
EditorGUI.PropertyField(singleFieldRect, scaleYProp);

singleFieldRect.y += EditorGUIUtility.singleLineHeight;
EditorGUI.PropertyField(singleFieldRect, scaleZProp);
}
}


References
Unity - Timeline 知识汇总

相关文档

  • 2017年6月大学英语六级作文范文:电子垃圾
  • 人身伤残等级鉴定标准人身伤残等级鉴定
  • 保护教室卫生的标语
  • 奥运会和冬奥会有什么区别详细点
  • 服装电话销售开场白
  • 铁路工程大跨径桥梁工程研究论文
  • 银行管理员竞选演讲稿
  • 六一儿童作品画
  • 初一下册地理考试重点
  • 做蛋挞的步骤有哪些
  • hight, low Temperature
  • 中国的科学技术具有整体性是什么意思
  • 初中白话文作者文学常识
  • GC垃圾回收常见算法
  • 交通安全讲座听后感范文
  • 最新鱼塘承包合同书范本
  • 新鲜草莓怎么清洗方法简单有效
  • 吃豌豆会发胖吗?豌豆的热量高吗?
  • Oracle+rac+关机流程,11g RAC 关机顺序
  • 老师您辛苦了作文400字|老师,您辛苦了!作文
  • 小班教学计划总结多篇
  • 卸妆步骤的先后顺序卸不好妆老十岁
  • 通用版乡村医生个人述职报告推荐
  • UiPath利用Open browser组件打开IE浏览器时报错Cannot communicate with Internet Explorer browser,而chrome及Firefox却正常
  • IEEE Conference模板中参考文献间距的调节
  • 楠野爸爸宝宝记忆枕好用吗楠野爸爸宝宝记忆枕孩子愿意用吗
  • 最早的中国动画片是怎样制作的
  • java计算二叉树的节点最小值_二叉树:我是不是一棵二叉搜索树
  • 建筑摄影基础知识教学
  • 最新先进个人发言稿三篇
  • 猜你喜欢

  • 最新2019-四年级上册语文课件-7.蟋蟀的住宅(人教新课标)(共34张PPT)-PPT课件
  • 七年级学期信息技术复*知识点(1)【DOC范文整理】
  • 安徽专版2018年春七年级英语下册Unit8同步作文指导*题课件
  • 快乐的中秋节_关于节日的作文800字
  • 河北省唐山市开滦第二中学2016-2017学年高一6月月考地理试题Word版含答案
  • 2018-周杰伦《一定要幸福》钢琴谱-精选word文档 (2页)
  • 黑龙江巨龙房地产经纪有限公司*房分公司企业信用报告-天眼查
  • 郑州优捷电子技术有限公司企业信用报告-天眼查
  • 【精编范文】人民教师师德师风学*的自查工作报告-实用word文档 (2页)
  • 【参考文档】个人年终工作计划范文-实用word文档 (1页)
  • 东师《小学教育研究方法2013春第一次在线作业
  • 2010年一建造师考试《通信与广电工程管理与实务的的案例题
  • 构筑“不想腐”的思想防线——抚顺市加强廉政警示教育工作综述
  • 丈夫和情人让我陷入两难,想挽救出轨婚姻
  • 2019-2020年部编本人教版小学小学一年级语文上册拼音复习测试试卷1
  • 小米粥有什么营养价值?
  • 小蝌蚪找妈妈改写作文500字
  • 部编版《美丽的冬天》ppt优秀课件19
  • MapReduce环境搭建步骤(伪分布式)(个人使用版)
  • 天空是怎么形成的有哪些原因
  • 如何做程序员的研发绩效管理?对话:奇虎360副总裁和原迅雷高级副总裁
  • 2020年新部编本四年级语文下册2 乡下人家 精品公开课课件
  • 专用机床市场前景预测及投资规划分析报告(目录)
  • 胰腺癌治疗现状
  • 面行天下镇江锅盖面
  • 广东话骂人句子
  • 绍兴市上虞区昊杰服饰厂(企业信用报告)- 天眼查
  • 轨道交通自动售检票(AFC)系统信息安全分析
  • 医院年终会议主持词
  • 张家港市后塍农村信用合作社企业信息报告-天眼查
  • 江苏大学2017年《885程序设计》考研专业课真题试卷
  • 头皮头发基础知识店长_美容化妆_生活休闲.ppt
  • 执行案件结案审批表
  • 构建综合实践教学*台,培养创新应用型人才,助力工商学院转型发展
  • linux-网络基础二
  • 人教版《道德与法治》七年级上册:3.2 做更好的自己 课件(共19张PPT)
  • 2012全国高中学生化学竞赛(江苏省赛区)选拔赛试题及答案
  • 甘肃省天水一中2018_2019学年高二政治下学期第一阶段考试试题
  • 2020淄博师范高等专科学校普通高等教育招生章程
  • 牡丹花的传说故事作文
  • 精品学习2019高考物理二轮复习专题三电场与磁场第3讲带电粒子在复合场中的运动突破练
  • 【K12教育学*资料】[学*]辽宁省庄河高级中学2017-2018学年高二数学下学期期末考试试题 文
  • 电脑版