Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Set ControlPlayableAsset clip's Source Game Object

Discussion in 'Timeline' started by hoperin, Apr 24, 2018.

  1. hoperin

    hoperin

    Joined:
    Feb 9, 2014
    Posts:
    52
    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' to `UnityEngine.ExposedReference<UnityEngine.GameObject>'

    This is the chunk of code in question:
    Code (CSharp):
    1. void AddControlClip(PlayableDirector TLparent, GameObject target, string name){
    2.  
    3.         TimelineAsset tl = TLparent.playableAsset as TimelineAsset;
    4.  
    5.         //find the control track;
    6.         TrackAsset track = tl.GetOutputTrack (0);
    7.  
    8.         //create the new clip on the TL
    9.         TimelineClip tlClip = track.CreateClip<ControlPlayableAsset>();
    10.         ControlPlayableAsset clip = tlClip.asset as ControlPlayableAsset;
    11.  
    12. [B]        //assign its target where target = Gameobject
    13.         clip.sourceGameObject = target;[/B]
    14.  
    15.         clip.postPlayback = ActivationControlPlayable.PostPlaybackState.Inactive;
    16.  
    17.     }
    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.
     
    Sarai likes this.
  2. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    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.
     
  3. hoperin

    hoperin

    Joined:
    Feb 9, 2014
    Posts:
    52
    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?
     
  4. hoperin

    hoperin

    Joined:
    Feb 9, 2014
    Posts:
    52
    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!
    ( https://forum.unity.com/threads/timeline-cinemachine-create-shots-by-script.482480/#post-3141845 )

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

    Code (CSharp):
    1. clip.sourceGameObject.exposedName = UnityEditor.GUID.Generate ().ToString ();
    2. TLparent.SetReferenceValue (clip.sourceGameObject.exposedName, target);
     
    IvanIvanovP3 and Pacosmico like this.
  5. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    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.
     
  6. Cleverlie

    Cleverlie

    Joined:
    Dec 23, 2013
    Posts:
    219
    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.
     
  7. BobMCleod

    BobMCleod

    Joined:
    Sep 15, 2017
    Posts:
    7
    How I would LOVE that! I am spending hours upon hours assembling small tidbits into a workable implementation too.
     
    dbdenny and Cleverlie like this.
  8. dbdenny

    dbdenny

    Joined:
    Mar 13, 2020
    Posts:
    12
    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:
    Code (CSharp):
    1. // 1. Create a clip and assign the sourceGameObject
    2. var newClip = track.CreateClip<ControlPlayableAsset>();
    3. var clipAsset = newClip.asset as ControlPlayableAsset;
    4. clipAsset.sourceGameObject.exposedName = GUID.Generate().ToString(); // When first expose, should assign an unique name
    5. director.SetReferenceValue(clipAsset.sourceGameObject.exposedName, go);
    6.  
    7. // 2. Just change an exist clip's sourceGameObject
    8. director.ClearReferenceValue(clipAsset.sourceGameObject.exposedName);
    9. director.SetReferenceValue(clipAsset.sourceGameObject.exposedName, go);
     
    Last edited: Nov 25, 2020