DefaultPlayables源码
DefaultPlayables在Unity原生的轨道支持下额外提供了7种轨道。
- LightControl
- NavMeshAgentControl
- ScreenFader
- Video
- TransformTween
- TimeDilation
- TextSwitcher
我们以LightControl为例,主要有以下4个脚本:
LightControlBehaviour、LightControlClip、LightControlMixerBehaviour、LightControlTrack
Editor下的绘制有一个脚本:
LightControlDrawer
结合我之前的文章:
Unity Timeline自定义轨道_漫漫无期的博客-CSDN博客
Timeline上的轨道由LightControlTrack进行管理。
在进行混合时创建出LightControlMixerBehaviour,Editor下获取绑定物体的灯光属性基础信息。
[TrackColor(0.9454092f, 0.9779412f, 0.3883002f)]
[TrackClipType(typeof(LightControlClip))]
[TrackBindingType(typeof(Light))]
public class LightControlTrack : TrackAsset
{
public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
{
return ScriptPlayable<LightControlMixerBehaviour>.Create (graph, inputCount);
}
public override void GatherProperties(PlayableDirector director, IPropertyCollector driver)
{
#if UNITY_EDITOR
Light trackBinding = director.GetGenericBinding(this) as Light;
if (trackBinding == null)
return;
driver.AddFromName<Light>(trackBinding.gameObject, "m_Color");
driver.AddFromName<Light>(trackBinding.gameObject, "m_Intensity");
driver.AddFromName<Light>(trackBinding.gameObject, "m_Range");
driver.AddFromName<Light>(trackBinding.gameObject, "m_BounceIntensity");
#endif
base.GatherProperties(director, driver);
}
}
LightControlMixerBehaviour 完成具体行为上的控制,可以看到,它首先在第一帧时记录下默认的灯光属性,然后通过playable.GetInput系列方法获取输入的各个Input并由他们的权重进行混合计算,得出结果后再赋值给绑定的物体Light m_TrackBinding。
最后在OnPlayableDestroy 还原其基本灯光属性。
public class LightControlMixerBehaviour : PlayableBehaviour
{
Color m_DefaultColor;
float m_DefaultIntensity;
float m_DefaultBounceIntensity;
float m_DefaultRange;
Light m_TrackBinding;
bool m_FirstFrameHappened;
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
m_TrackBinding = playerData as Light;
if (m_TrackBinding == null)
return;
if (!m_FirstFrameHappened)
{
m_DefaultColor = m_TrackBinding.color;
m_DefaultIntensity = m_TrackBinding.intensity;
m_DefaultBounceIntensity = m_TrackBinding.bounceIntensity;
m_DefaultRange = m_TrackBinding.range;
m_FirstFrameHappened = true;
}
int inputCount = playable.GetInputCount ();
Color blendedColor = Color.clear;
float blendedIntensity = 0f;
float blendedBounceIntensity = 0f;
float blendedRange = 0f;
float totalWeight = 0f;
float greatestWeight = 0f;
int currentInputs = 0;
for (int i = 0; i < inputCount; i++)
{
float inputWeight = playable.GetInputWeight(i);
ScriptPlayable<LightControlBehaviour> inputPlayable = (ScriptPlayable<LightControlBehaviour>)playable.GetInput(i);
LightControlBehaviour input = inputPlayable.GetBehaviour ();
blendedColor += input.color * inputWeight;
blendedIntensity += input.intensity * inputWeight;
blendedBounceIntensity += input.bounceIntensity * inputWeight;
blendedRange += input.range * inputWeight;
totalWeight += inputWeight;
if (inputWeight > greatestWeight)
{
greatestWeight = inputWeight;
}
if (!Mathf.Approximately (inputWeight, 0f))
currentInputs++;
}
m_TrackBinding.color = blendedColor + m_DefaultColor * (1f - totalWeight);
m_TrackBinding.intensity = blendedIntensity + m_DefaultIntensity * (1f - totalWeight);
m_TrackBinding.bounceIntensity = blendedBounceIntensity + m_DefaultBounceIntensity * (1f - totalWeight);
m_TrackBinding.range = blendedRange + m_DefaultRange * (1f - totalWeight);
}
public override void OnPlayableDestroy (Playable playable)
{
m_FirstFrameHappened = false;
if(m_TrackBinding == null)
return;
m_TrackBinding.color = m_DefaultColor;
m_TrackBinding.intensity = m_DefaultIntensity;
m_TrackBinding.bounceIntensity = m_DefaultBounceIntensity;
m_TrackBinding.range = m_DefaultRange;
}
}
LightControlClip、LightControlBehaviour 数据来源。在LightControlClip的CreatePlayable方法中完成将template数据传递过去的责任。
[Serializable]
public class LightControlClip : PlayableAsset, ITimelineClipAsset
{
public LightControlBehaviour template = new LightControlBehaviour ();
public ClipCaps clipCaps
{
get { return ClipCaps.Blending; }
}
public override Playable CreatePlayable (PlayableGraph graph, GameObject owner)
{
var playable = ScriptPlayable<LightControlBehaviour>.Create (graph, template);
return playable; }
}
[Serializable]
public class LightControlBehaviour : PlayableBehaviour
{
public Color color = Color.white;
public float intensity = 1f;
public float bounceIntensity = 1f;
public float range = 10f;
}
LightControlDrawer负责Editor下的检视面板的自定义绘制。
[CustomPropertyDrawer(typeof(LightControlBehaviour))]
public class LightControlDrawer : PropertyDrawer
{
public override float GetPropertyHeight (SerializedProperty property, GUIContent label)
{
int fieldCount = 4;
return fieldCount * EditorGUIUtility.singleLineHeight;
}
public override void OnGUI (Rect position, SerializedProperty property, GUIContent label)
{
SerializedProperty colorProp = property.FindPropertyRelative("color");
SerializedProperty intensityProp = property.FindPropertyRelative("intensity");
SerializedProperty bounceIntensityProp = property.FindPropertyRelative("bounceIntensity");
SerializedProperty rangeProp = property.FindPropertyRelative("range");
Rect singleFieldRect = new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight);
EditorGUI.PropertyField(singleFieldRect, colorProp);
singleFieldRect.y += EditorGUIUtility.singleLineHeight;
EditorGUI.PropertyField(singleFieldRect, intensityProp);
singleFieldRect.y += EditorGUIUtility.singleLineHeight;
EditorGUI.PropertyField(singleFieldRect, bounceIntensityProp);
singleFieldRect.y += EditorGUIUtility.singleLineHeight;
EditorGUI.PropertyField(singleFieldRect, rangeProp);
}
}
其他6种轨道结构也与此类似,不一一展开。
Default Playables辅助工具
可以看下这篇文章更详细的介绍:
Unity - Timeline 自定义剪辑,轨道,混合轨道,Inspector属性显示(使用Default Playables辅助工具)_Jave.Lin 的学习笔记-CSDN博客
打开辅助工具的向导面板。
Playable Name
首先是我们的剪辑名字。如:TestScale。
那么工具会帮助我们自动创建以下几个类:
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,的额外两种。
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
轨道的颜色。
Create Drawer
是否创建剪辑的Inspector属性绘制器。