当前位置: 首页 > news >正文

TimeLine如何自定义轨道

一套清晰、可扩展的 Timeline + 对话系统 框架设计,旨在实现精确暂停/恢复和事件驱动解耦,用作使用参考,如何自己定义播放轨道,Playable是Unity实现动画系统的底层逻辑,实际上无论是Animator还是Timeline的实现实际上都使用了它。
TimelineController —— 每个 Timeline 的专属控制器

usingUnityEngine;usingUnityEngine.Playables;/// <summary>/// 挂载在包含 PlayableDirector 的游戏对象上,负责单个 Timeline 的播放控制/// </summary>[RequireComponent(typeof(PlayableDirector))]publicclassTimelineController:MonoBehaviour{privatePlayableDirectordirector;privatePlayableGraphgraph;voidAwake(){director=GetComponent<PlayableDirector>();graph=director.playableGraph;}/// <summary> 暂停 Timeline(通过设置速度 = 0)</summary>publicvoidPause(){if(graph.IsValid()){graph.GetRootPlayable(0).SetSpeed(0d);Debug.Log($"[{name}] Timeline paused");}}/// <summary> 恢复 Timeline(速度 = 1)</summary>publicvoidResume(){if(graph.IsValid()){graph.GetRootPlayable(0).SetSpeed(1d);Debug.Log($"[{name}] Timeline resumed");}}/// <summary> 停止并重置 Timeline(回到起点)</summary>publicvoidStop(){director.Stop();}/// <summary> 直接播放/恢复(如果已暂停则继续)</summary>publicvoidPlay(){director.Play();}/// <summary> 获取当前播放状态</summary>publicPlayStateState=>director.state;/// <summary> 获取或设置播放时间</summary>publicdoubleTime{get=>director.time;set=>director.time=value;}}

TimelineManager —— 全局管理器(单例)

usingSystem.Collections.Generic;usingUnityEngine;/// <summary>/// 全局 Timeline 管理器,负责注册所有 TimelineController,/// 并提供按名称/ID 暂停恢复的功能。/// </summary>publicclassTimelineManager:Singleton<TimelineManager>{privateDictionary<string,TimelineController>timelines=newDictionary<string,TimelineController>();/// <summary> 注册一个 Timeline(通常由 TimelineController 自己在 Start/Awake 时调用)</summary>publicvoidRegisterTimeline(stringid,TimelineControllercontroller){if(!timelines.ContainsKey(id))timelines.Add(id,controller);elseDebug.LogWarning($"Timeline with id{id}already exists!");}/// <summary> 注销(对象销毁时调用)</summary>publicvoidUnregisterTimeline(stringid){if(timelines.ContainsKey(id))timelines.Remove(id);}/// <summary> 通过 ID 获取 TimelineController </summary>publicTimelineControllerGetTimeline(stringid){timelines.TryGetValue(id,outvarctrl);returnctrl;}/// <summary> 暂停指定 ID 的 Timeline </summary>publicvoidPauseTimeline(stringid){if(timelines.TryGetValue(id,outvarctrl))ctrl.Pause();}/// <summary> 恢复指定 ID 的 Timeline </summary>publicvoidResumeTimeline(stringid){if(timelines.TryGetValue(id,outvarctrl))ctrl.Resume();}/// <summary> 暂停当前所有活跃的 Timeline </summary>publicvoidPauseAll(){foreach(varctrlintimelines.Values)ctrl.Pause();}/// <summary> 恢复所有 Timeline </summary>publicvoidResumeAll(){foreach(varctrlintimelines.Values)ctrl.Resume();}}

DialogueBehaviour —— 对话行为(PlayableBehaviour)

usingUnityEngine;usingUnityEngine.Playables;[System.Serializable]publicclassDialogueBehaviour:PlayableBehaviour{publicDialoguePiecedialoguePiece;// 对话数据(ScriptableObject 或普通类)privatePlayableDirectordirector;privatestringtimelineId;// 用于向管理器暂停时识别 TimelinepublicoverridevoidOnPlayableCreate(Playableplayable){// 获取当前 Timeline 的 Directordirector=playable.GetGraph().GetResolver()asPlayableDirector;if(director!=null){// 用 Director 所在对象的名称作为 Timeline ID(也可自定义)timelineId=director.gameObject.name;}}publicoverridevoidOnBehaviourPlay(Playableplayable,FrameDatainfo){// 触发对话显示事件(由 UI 系统监听)EventHandler.CallShowDialogueEvent(dialoguePiece);if(Application.isPlaying){if(dialoguePiece!=null&&dialoguePiece.hasToPause){// 需要暂停当前 Timeline// 通过全局管理器暂停对应 ID 的 TimelineTimelineManager.Instance.PauseTimeline(timelineId);}else{// 没有暂停需求,确保隐藏之前的对话(可选)EventHandler.CallShowDialogueEvent(null);}}}publicoverridevoidOnBehaviourPause(Playableplayable,FrameDatainfo){// 当 Timeline 离开该片段时,可能也需要隐藏对话// 但要注意:暂停时也会调用 OnBehaviourPause,需要区分// 简单起见,可以用标志位判断是否因为暂停而离开// 这里示例:如果是因为结束而离开,则隐藏对话if(info.evaluationType==FrameData.EvaluationType.Playback)// 正常播放结束{EventHandler.CallShowDialogueEvent(null);}}}

DialogueClip 和 DialogueTrack

usingUnityEngine;usingUnityEngine.Playables;usingUnityEngine.Timeline;// 对话片段[System.Serializable]publicclassDialogueClip:PlayableAsset,ITimelineClipAsset{publicClipCapsclipCaps=>ClipCaps.None;// 可编辑的对话行为实例publicDialogueBehaviourdialogue=newDialogueBehaviour();publicoverridePlayableCreatePlayable(PlayableGraphgraph,GameObjectowner){// 将 dialogue 复制到 Playable 中varplayable=ScriptPlayable<DialogueBehaviour>.Create(graph,dialogue);returnplayable;}}// 对话轨道[TrackClipType(typeof(DialogueClip))]publicclassDialogueTrack:TrackAsset{// 轨道不需要额外逻辑,默认混合行为即可}

这套框架将 Timeline 控制与具体业务逻辑(对话)解耦,同时提供了精确的暂停机制,非常适合用在剧情演出、过场动画等场景,但是还有有很多没完善的,没考虑,主要作为一个参考。

http://www.jsqmd.com/news/485253/

相关文章:

  • 035-spiderbuf第C12题
  • 嘎嘎降AI和笔灵AI哪个好?花200块实测对比告诉你
  • 手把手教你用嘎嘎降AI处理毕业论文:从上传到下载全流程 - 我要发一区
  • 计算机毕业设计java基于个性化推荐的众筹系统 基于用户画像的智能众筹平台的设计与开发 融合个性化推荐机制的创意项目融资系统的构建与实现
  • 品牌设计集团如何选择?
  • 基于SpringCloud的电子商城系统设计与应用
  • 2026年知网最新AIGC检测算法应对攻略 - 我要发一区
  • InnoDB中的undo日志和历史系统的基础机制
  • 四轮驱动汽车的线控转向系统失效+轨迹跟踪和横摆稳定性、失效容错控制仿真(带复现参考文献)
  • 降AI工具售后对比:退款政策/修改次数/客服响应 - 我要发一区
  • 【无人机通信】考虑Nakagami-m衰落和逆伽马阴影衰落效应的空中智能反射面辅助无线通信系统(无人机群改型)附matlab代码
  • 初创企业数字化基础工具白皮书——中资源企业邮箱解决方案 - 优质品牌商家
  • C++——数组类模板
  • LCM,GCD
  • 5款降AI工具实测对比:价格从4块到10块效果差多少
  • 什么是 SMD 封装?是不是都不带引脚?
  • 宝宝敏感肌安心护肤油
  • Java面试复盘笔记,2026突击必备!
  • Matlab速成笔记七十三:三角函数运算的用法
  • 虚拟机安装流程
  • Docker 核心知识点
  • 国产AI驱动的超自动化巡检“龙虾”来了
  • 基于SpringBoot的中华历史故事展播系统设计与应用
  • 微短剧《嘉庆君游台湾》开机 童星麦片(吴羽朔)助力嘉庆渡台行
  • 古镇文旅旧改活化优质公司推荐:游玩体验提升效果解析
  • 智能体驱动的企业IT架构转型
  • AI 编程能力边界探索:一次 Claude Code 实战,揭开 Spec Coding 的真正价值
  • 打家劫舍 和 打家劫舍 II
  • 第7章 基、坐标与线性变换:空间的视角与重构
  • Thinkphp和Laravel框架都支持基于微信小程序的校园互助论坛学习社区95l77