Set ControlPlayableAsset clip's Source Game Object

Everytime I think I've finally got a handle on Timeline another thign throws me off. I'm trying to set the target of the ControlPlayableAsset clips that I'm spawning on a Control Track. I'm getting this error:

Cannot implicitly convert type UnityEngine.GameObject' toUnityEngine.ExposedReference'

This is the chunk of code in question:

void AddControlClip(PlayableDirector TLparent, GameObject target, string name){

        TimelineAsset tl = TLparent.playableAsset as TimelineAsset;

        //find the control track;
        TrackAsset track = tl.GetOutputTrack (0);

        //create the new clip on the TL
        TimelineClip tlClip = track.CreateClip<ControlPlayableAsset>();
        ControlPlayableAsset clip = tlClip.asset as ControlPlayableAsset;

[B]        //assign its target where target = Gameobject
        clip.sourceGameObject = target;[/B]

        clip.postPlayback = ActivationControlPlayable.PostPlaybackState.Inactive;

    }

where

clip.sourceGameObject = target;

is the culprit...

Thanks in advance! I'm sure it's just a simple syntax thing like all myprevious Timeline issues but I just don't get this one.

1 Like

use TLparent.SetReferenceValue(clip.sourceGameObject.exposedName, target);

Because Timeline is an asset, scene references cannot be set directly on clips, so instead an exposed reference is used, which is just a lookup id. The actual gameObject is stored in a lookup table inside the playable director.

Thanks for the reply! This half works – it assigns the right target, but it also overwrites each control clip on the track so that they all target it, not just the single clip I’m trying to target.

I guess this is because it’s applying the target to the playableDirector as a whole? But there must be a way to assign exposed references individually?

Just wanted to throw in an update for anyone who is having the same issue that I figured out what was missing thanks to another thread dealing with exposed references!
( Timeline + Cinemachine : create Shots by script )

I was missing initialization of exposedName (whatever that does, I’m not sure at all honestly, but it works!)

clip.sourceGameObject.exposedName = UnityEditor.GUID.Generate ().ToString ();
TLparent.SetReferenceValue (clip.sourceGameObject.exposedName, target);
2 Likes

Yes, that’s a good point that I missed. The exposed reference does that when you view it in the editor, but when creating them from script the exposedName has a default value.

You can set the exposedName to something meaningful (instead of a GUID)
clip.sourceGameObject.exposedName = “LookAtTarget”;
TLparent.SetReferenceValue(new PropertyName(“LookAtTarget”), target);

In that case, the string should show appear in the inspector.

it would be really useful if this tiny bits and snippets of code are added in a pedagogical way to the unity official documentation. I find myself having to copy this little snippets in a folder and organize them myself to keep track of how to work with timeline, the information is very disperse and only googling with a good eye you encounter this answers to questions and threads made a time ago, just a suggestion for the people handling the documentation.

5 Likes

How I would LOVE that! I am spending hours upon hours assembling small tidbits into a workable implementation too.

2 Likes

When I create a track and a clip, set reference with this method can work, but when I want to change an exist asset, this method cannot work…
Hope I can find the reason and post here…


I’m back!
The SetReferenceValue failed in my case just because I load the prefab with PrefabUtility.LoadPrefabContents(prefabPath); Seems this method only works when the prefab is loaded in the current active scene by something like PrefabUtility.InstantiatePrefab(prefab);

So if anyone want to change the reference of something like aTimelineAsset.sourceGameObject, can do like this:

// 1. Create a clip and assign the sourceGameObject
var newClip = track.CreateClip<ControlPlayableAsset>();
var clipAsset = newClip.asset as ControlPlayableAsset;
clipAsset.sourceGameObject.exposedName = GUID.Generate().ToString(); // When first expose, should assign an unique name
director.SetReferenceValue(clipAsset.sourceGameObject.exposedName, go);

// 2. Just change an exist clip's sourceGameObject
director.ClearReferenceValue(clipAsset.sourceGameObject.exposedName);
director.SetReferenceValue(clipAsset.sourceGameObject.exposedName, go);