I have a case where I have one player character object instance that is used across couple of additively loaded scenes. Right now Timelines exposed variables doesn't work with multi scene setup. But event if it did I'ld like to make my player character object be spawned dynamicaly at the begining of gamaplay insted of having it sitting on a specific scene. To achieve what I need I could recreate the AnimationTrack so it would find reference when it starts playing. But I haven't found source code for the AnimationTrack and I would probably recreate it poorly. Second option is use a proxy object when setting up timeline and change it on runtime. But I see only "get" method avaible ( PlayableDirector.GetGenericBinding ). And even if this get method is the way to go I cannot figure it out. I would apreciate help with any of the two approaches.
If I understand correctly, you are trying to bind a track to a dynamically spawned object. You can use PlayableDirector.SetGenericBinding(track, gameObject), and get the track by either searching through the timeline, or by searching through the bindings: Here's an example that shows both methods (attached to the dynamically spawned object): Code (CSharp): using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Timeline; using UnityEngine.Playables; public class DynamicBind : MonoBehaviour { public string trackName = "MyCharacterTrack"; // Use this for initialization void Start () { var animator = GetComponent<Animator>(); var playableDirectors = FindObjectsOfType<PlayableDirector>(); foreach (var director in playableDirectors) { // method 1, using generic playable assets if (director.playableAsset != null) { foreach (var binding in director.playableAsset.outputs) { if (binding.streamName == trackName) director.SetGenericBinding(binding.sourceObject, animator); } } // method2, using timeline var timelineAsset = director.playableAsset as TimelineAsset; if (timelineAsset != null) { foreach (var track in timelineAsset.GetOutputTracks() { if (track is AnimationTrack && track.name == trackName) director.SetGenericBinding(track, animator); } } } } }
Thanks @seant_unity ! It works! Not I understand. Using method 1 I have to gather all tracks with director.playableAsset.outputs, then I use reference to a track to get binding object with director.GetGenericBinding. Then I check if GetGenericBinding returned my proxy object. If so I replace it with SetGenericBinding. It seams there's a lot going on under the hood in Timeline and it's hard to get a head around all those classes
It works indeed but the track name is something most tracks don't have like an AnimatorTrack or CinemachineTrack. How to rebind a specific AnimatorTrack for example?
The track name can be assigned in the inspector for the track. If a track has a binding, it shows that instead of the name, but the name still exists.