# TimelineScript **Repository Path**: eloncode/TimelineScript ## Basic Information - **Project Name**: TimelineScript - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-08 - **Last Updated**: 2026-04-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # TimelineScript TimelineScript一开始是用来设计技能而实现的一套数据驱动框架脚本,方便策划设计天马行空的表现。在框架逐渐完善以后,发现,他可以做很多意想不到的事情。 首先解释一下为什么要命名为TimelineScript 在游戏中,不管是技能或者是过场都是以时间线为单位进行各种元素、逻辑的组织,完成一段定制好的剧本效果。参考现代化的引擎,如Unity的Timeline,UE的Sequencer,都是提供过场动画序列编辑器,许多游戏也会使用它制作技能和剧情,有完善的工具链,支持效果预览,时间线调度,制作固定的影片级效果,在编辑动画,镜头效果,多主体联动、混合处理上很有优势,相应的就会缺失逻辑编辑的能力。 而如果一段剧本高度依赖逻辑交互,需要根据动态的数据播放不同的效果,甚至是需要走条件分支,就很难和动画序列编辑器搭配使用。而最擅长逻辑编辑的工具,其实就是行为树,可以处理复杂的状态转换逻辑,而我理解的最理想的剧本制作,是基于时间轴的行进式剧情播放加逻辑编辑能力的组合,所以诞生了这个框架。 从Gameplay开发的角度上看,程序的职责是负责提供易用高效的生产方式,而策划、美术则是内容的主要生产者。策划只生产数据,而把策略定制的过程交给程序,程序通过数据驱动的方式,把职责(脏活)转移给策划(干得漂亮),这就是一个玩法开发者的自我修养。 若以技能为例,我们知道每个新技能势必要创建大量的游戏逻辑,如果每个技能都需要程序参与开发,配置,则是脱离了程序工作的范畴,让编程的魅力,以及效率都大打折扣。而技能是一套涵盖逻辑判断、表现差异化,包含状态转换、游戏数值调整,内容播放的集合,想要实现让策划主导生产,就需要为策划提供开发上层逻辑的能力。这也是为什么大型的团队制作技能都会开发一套脚本系统。 我们想要模块化的代码尽可能多地被复用,我们不会把一个特性功能的需求看作是一组垂直功能的堆叠,而是会去设计并实现这个特性所需的基础功能组件,保证它的通用性。 我们更需要一个清晰的、明确的、最好是视图的方式,使得脚本开发者对逻辑流向和状态转移能直接地、完全地掌控。在节点的结构设计上,树结构应该是最优选择。 ![image](https://user-images.githubusercontent.com/5411865/109384631-32554080-7929-11eb-91b4-0524e73cdd27.png) # Timeline TimeLine 作为技能播放的时间线,管理多个的TimeLineClip,实现不同的施法阶段的定义。TimeLine 在配置/编辑器中对用户透明,在程序中管理该脚本中所有的Clip 节点。Clip需要配置开始和结束的时间区间,Clip时间区间可以重合、叠加,互不干扰,并且支持设置循环模式。Clip 下可以添加Action 节点或者Controller 节点,这样基本完成了基于时间线的结构模型。 # Controller Parallel,Sequence,Delay,三种基本的流程调度控制节点,分别按并发,串行和延时执行,相互组合可以实现绝大部分场景功能。这样看就跟行为树很像了,那为什么不再加个Selector?因为考虑技能的实际需求,终究是对多个操作的时间上的调度,Selector 在这里就比较鸡肋,而且策划不太擅长使用Selector,而且在分支的设计上,还是更倾向于添加新的节点类型,可以装饰在所有节点上,可以叫做条件节点,由于C#的这版没有维护,所以少了条件节点,这里不介绍了。感兴趣的可以自己加上。调度节点之间可以相互嵌套。 Parallel:包含多节点的一个集合,运行时会同时执行所有的子节点。 Sequence:包含多节点的一个集合,运行时会按顺序执行所有的子节点,前面的任务完成了才会继续执行后面的任务。 Delay:延时执行,节点下放置其他的节点 # Action 负责具体的技能内容,尽量细化拆分不同的功能,形成多个原子功能组件,策划通过组合原子功能,实现技能需求。整个生命周期会被限制在Timeline 的clip 中。 通过C#的反射能力,解释器可以把脚本里的配置,直接对运行时的对象进行正确的赋值,支持所有的内置基础类型。 举例:增加一个新的行为,让演员播放一个动画,只需要添加一个新的行为了,定义参数和行为 ```C# /// /// 播放动画 /// [Serializable] [InterpreterType(ScriptInterpreterType.Action)] public class PlayAction : Action { public string ActionName = ""; public override void OnStart() { actor?.PlayAction(ActionName, 1.0f); } } ``` 就在脚本中直接可以使用了,让演员二倍速播放"Standard_Action"动作,不需要去做额外的配置解析,类型注册 ```JSON "PlayAction": { "ActionName": "Standard_Action", "Rate": "2.0" } ``` 更多的惊喜,比如Clip片段过滤器,基础属性修改,共享黑板数据,剧本继承(对,就是那个继承)等等等等,可以自己在框架里发掘,这里就多说了。 # 可视化编辑器 可视化编辑器可以使用一个开源的项目https://github.com/pruttned/owl-bt ,链接中有详细的使用教程,配备四种节点 Composite 用来组合调度子节点 Task 执行实际任务的节点 Decorator 装饰器,用来实现条件判断, 打断退出, 循环判断, 改变返回结果等功能. Service 类似于装饰器,定时循环执行 感兴趣可以去适配一下这个编辑器,最终的效果应该是这样的: ![image](https://user-images.githubusercontent.com/5411865/109384651-4a2cc480-7929-11eb-8c7c-50d35e2262b6.png)