Contents

06Timeline扩展相关

06Timeline扩展相关

Timeline是游戏开发中常见的工具。因为游戏是一个随着时间演变的过程。定义随时间的变化一系列事物是游戏中必然会涉及的功能。短如定义技能动作释放与特效逻辑配合。长如一段演出的定义。都可以视为在时间轴上的演变。

准确来说,在时间维度上的演变操作,是可以被Timeline这样一个结构所描述的。

timeline相关文档 https://docs.unity3d.com/Packages/com.unity.timeline@1.8/manual/index.html

教学视频 https://www.bilibili.com/video/BV1gt4y1Y7LY/?p=2&spm_id_from=333.880.my_history.page.click&vd_source=8d35ead0946519f56d2ab5f9c83045df

扩展 https://blog.unity.com/engine-platform/extending-timeline-practical-guide

这里主要记录Tmeline扩展相关结构。Timeline部分还有很多细节待其他文档逐步补全。

Timeline基础介绍

Timeline是Unity自带的一个时间轴编辑窗口。其整体结构如下:

横轴方向表示的即是时间。纵向上则表示的是一条条轨道(Track)。每一条Track都代表不同的控制功能。Unity提供了6个基础的控制轨道,如图。通过右键可以在每条轨道上添加对应的区间块,称之为Clip。每一个Clip相当于表示在这段时间块内,对对应对象的控制。

对于每个Tack具体的使用方法可以参考上面的B站视频。这里只简单陈述:

  • ActivationTrack:主要控制目标对象的激活属性。
  • AnimationTrack:基于Animator组件,可以播放动画。也可以通过记录模式,直接Key帧控制对象物体的位移旋转。
  • AudioTrack:控制声音空间的播放。
  • ControlTrack:控制轴。主要用来控制那些可以播放的组件,控制对应结构的播放时间。例如其他Timeline构成的Sub-Timeline结构。粒子系统,以及实现ITimeControl的脚本等。
  • PlayableTrack:这个Track主要用来容纳那些工程中继承PlayableAsset的Clip。执行相应Clip的播放操作。这些会在后面的基础扩展中解释道。该轨道没有明确的Owner。

Timeline基础扩展

主要记录文档中介绍 unity对Timeline的建模,也是遵循逻辑与行为分离的方针。即存储数据的对象与运行时驱动的对象是分离的。这也符合Timeline编辑的需求。因为通常来说,对于timeline的使用是一个离线的编辑系统。即

  • 编辑时,可以方便的编辑并预览一个按时间运行的效果。同时需要保存成一份数据。
  • 运行时,根据之前保存的数据,在运行环境下执行对应操作,来复现编辑时候对应效果。

这里存在这两个环境,一个是编辑的环境,一个是运行时的环境。两个环境之间是需要一个方式来传递。即保存的数据。同时两个环境之间也有一定差异。因为运行时存在很多运行时才有的状况,需要根据某些情况来进行变化。而这属于在时间轴推进的基础上再做演变。

整个结构可以简单的如下图表示

以一个示例中给出了一个简单的例子为例,随时间对灯光的控制。按结构定义了如下三个部分:

  • LightControlAsset:对灯光控制的Asset数据对象。
  • LightControlBehaviour:对灯光的行为控制。
  • LightControlTrack:灯光控制轴。

其中LightControlTrack是一个空数据结构,只是用来声明这个Track上可以使用的PlayableAsset结构:

1
2
3
4
5
//TrackClipType 声明什么类型的Clip可以放在该轴上
[TrackClipType(typeof(Track_LightControlAsset))]
//TrackBindingType 该Track可以绑定一个什么类型的对象
[TrackBindingType(typeof(Light))]
public class Track_LightControlTrack : TrackAsset {}

而PlayableAsset则主要承担了两件事情。

  • 灯光控制执行时,需要预先编辑存放的数据。例如灯光颜色,亮度等等。以及一个需要预先放置,但是只在运行时需要绑定的灯光对象。可以注意到,有一部分数据是可以预先指定的。而还有一些对象,是需要跟着运行时环境所发生变化的。于是需要一个方式来进行区分。
  • 创建出对应的Behaviour对象。来承担该Clip开始时,运行时,结束时等一些时间节点的逻辑执行效果。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
public class Track_LightControlAsset : PlayableAsset, ITimelineClipAsset
{
    // 编辑时声明的对象类型字段 注意的是light需要预览,运行时绑定不同对象。所以这需要什么一个ExposedReference超类型
	// public ExposedReference<Light> light;
	public Color color = Color.white;
	public float intensity = 1f;

	public override Playable CreatePlayable (PlayableGraph graph, GameObject owner)
	{
		var playable = ScriptPlayable<Track_LightControlBehaviour>.Create(graph);
		// 生成对应的PlayableBehaviour来执行运行时效果
        // 运行预览时,则通过PlayableGraph对象来找到对应对象来进行bind操作 如果对应的对象绑定在track上 则会直接通过PlayerData传递给Behaviour对象
		var lightControlBehaviour = playable.GetBehaviour();
		// lightControlBehaviour.light = light.Resolve(graph.GetResolver());
		lightControlBehaviour.color = color;
		lightControlBehaviour.intensity = intensity;

		return playable;   
	}
}

而PlayableBehaviour对象功能则更为简单具体,其有一系列调用时点接口,在调用时触发。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
public class Track_LightControlBehaviour : PlayableBehaviour
{
	// public Light light;
    public Color color;
    public float intensity;

	public override void ProcessFrame(Playable playable, FrameData info, object playerData)
	{
        // 从playerData中获取对应的light 然后执行对应的设置行为
        Light light = playerData as Light;

		if (light != null)
		{
			light.color = color;
			light.intensity = intensity;
		}
	}
}

以上主要都是示例网站中的示例结构。主要用来对Timeline结构组成起到一个说明作用。示例中还介绍了如何自定义Mixer混合效果,添加template来添加key镇功能。这里不做过多介绍,原文已经讲解的非常好了。

这里主要再记录Timeline整体结构的在编辑时,运行时,等结构细节。