Unity单场景运行时切换Playable Asset丢失引用问题求助
解决Unity Timeline运行时切换Playable Asset丢失GameObject引用问题
不需要为每个Timeline单独创建Playable Director,同一个Director完全可以复用,问题出在切换时没有同步Timeline的绑定信息。以下是具体解决步骤和代码实现:
核心原因
每个Playable Asset(Timeline资源)的GameObject绑定信息关联在Playable Director的Playable Bindings中,直接调用director.Play(playableAsset)只会替换Timeline资源,但不会自动同步新Timeline的绑定配置,导致引用丢失。
解决步骤
- 编辑器提前配置绑定:分别打开Timeline A和Timeline B,在编辑器中为它们的轨道绑定好对应场景GameObject,确保编辑状态下播放正常。
- 脚本存储绑定映射:在Awake阶段读取并存储每个Timeline的绑定关系,切换时重新应用这些绑定。
- 切换时同步绑定并播放:停止当前播放,清空旧绑定,应用目标Timeline的绑定,再设置并播放新Timeline。
完整代码示例
挂载在TimelineManager GameObject上的脚本:
using UnityEngine; using UnityEngine.Playables; using System.Collections.Generic; public class TimelineSwitcher : MonoBehaviour { public PlayableDirector playableDirector; public PlayableAsset timelineA; public PlayableAsset timelineB; // 存储每个Timeline的绑定:轨道源对象 -> 目标GameObject private Dictionary<PlayableAsset, Dictionary<Object, Object>> _timelineBindings = new Dictionary<PlayableAsset, Dictionary<Object, Object>>(); void Awake() { // 初始化Timeline A的绑定 if (timelineA != null) { var bindings = new Dictionary<Object, Object>(); foreach (var output in timelineA.outputs) { var boundObj = playableDirector.GetGenericBinding(output.sourceObject); if (boundObj != null) { bindings.Add(output.sourceObject, boundObj); } } _timelineBindings.Add(timelineA, bindings); } // 初始化Timeline B的绑定 if (timelineB != null) { var bindings = new Dictionary<Object, Object>(); foreach (var output in timelineB.outputs) { var boundObj = playableDirector.GetGenericBinding(output.sourceObject); if (boundObj != null) { bindings.Add(output.sourceObject, boundObj); } } _timelineBindings.Add(timelineB, bindings); } } void Update() { if (Input.GetKeyDown(KeyCode.Space)) { SwitchAndPlayTimeline(timelineA); } else if (Input.GetKeyDown(KeyCode.Return)) { SwitchAndPlayTimeline(timelineB); } } void SwitchAndPlayTimeline(PlayableAsset targetTimeline) { if (targetTimeline == null || !_timelineBindings.ContainsKey(targetTimeline)) return; // 停止当前Timeline播放 playableDirector.Stop(); // 清空现有绑定 if (playableDirector.playableAsset != null) { foreach (var output in playableDirector.playableAsset.outputs) { playableDirector.SetGenericBinding(output.sourceObject, null); } } // 应用目标Timeline的绑定 foreach (var bindingKvp in _timelineBindings[targetTimeline]) { playableDirector.SetGenericBinding(bindingKvp.Key, bindingKvp.Value); } // 设置并播放新Timeline playableDirector.playableAsset = targetTimeline; playableDirector.Play(); } }
使用说明
- 在Inspector面板中,将TimelineManager上的Playable Director组件拖入
playableDirector字段。 - 将Timeline A和Timeline B资源分别拖入对应的字段。
- 运行场景后,按空格键播放Timeline A,回车键播放Timeline B,此时绑定的GameObject引用不会丢失。
内容的提问来源于stack exchange,提问作者어우석
相关产品推荐
相关产品推荐

