Search Unity

Set ExposedReference StreamPlayer of Alembic Shot Asset

Discussion in 'Timeline' started by johhnry, Jun 22, 2021.

  1. johhnry

    johhnry

    Joined:
    Jan 7, 2020
    Posts:
    2
    Hi,

    I am creating some Alembic tracks with C# from alembic prefabs instantiated in the scene.

    When doing it in the interface by drag and dropping the objects in the track, it works and it creates an Alembic Shot Asset with the Stream Player set to the Alembic Stream Player script of the prefab so the animation is referenced.

    Now I need to do this with code so I currently have this :

    Code (CSharp):
    1.  
    2. // Create an alembic track
    3. AlembicTrack alembicTrack = playableTimeline.CreateTrack<AlembicTrack>();
    4.  
    5. // Create alembic clip
    6. TimelineClip alembicClip = alembicTrack.CreateClip<AlembicShotAsset>();
    7.  
    8. // Get alembic player script in prefab
    9. AlembicStreamPlayer streamPlayerScript = selectedPrefabInstance.GetComponent<AlembicStreamPlayer>();
    10.  
    11. // Get Alembic shot asset
    12. AlembicShotAsset alembicShotAsset = (alembicClip.asset as AlembicShotAsset);
    13.  
    14. // Set the exposed reference
    15. ExposedReference<AlembicStreamPlayer> streamPlayerReference = alembicShotAsset.StreamPlayer;
    16. streamPlayerReference.exposedName = UnityEditor.GUID.Generate().ToString();
    17. playableDirector.SetReferenceValue(streamPlayerReference.exposedName, streamPlayerScript);
    (selectedPrefabInstance is a prefab instance in the scene)

    So I need to set the StreamPlayer reference of the Alembic shot asset but it's an exposed reference and I found this thread :

    https://forum.unity.com/threads/timeline-cinemachine-create-shots-by-script.482480/#post-3141845

    I tried the solution above but it doesn't seem to work...

    Is it the right way to do this?

    PS:
    I am using
    Unity 2020.3.9f1
    Timeline 1.5.5
    Alembic 2.1.3
     
  2. vladala

    vladala

    Unity Technologies

    Joined:
    Mar 3, 2017
    Posts:
    189
    Hey,

    I checked the following code that it creates the correct thing:
    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3. using UnityEngine.Formats.Alembic.Importer;
    4. using UnityEngine.Formats.Alembic.Timeline;
    5. using UnityEngine.Playables;
    6. using UnityEngine.Timeline;
    7.  
    8. namespace NUnit.Framework.Internal
    9. {
    10.     public class Class
    11.     {
    12.         [MenuItem("Window/DoIt")]
    13.         public static void DoIt()
    14.         {
    15.             var tl = ScriptableObject.CreateInstance<TimelineAsset>();
    16.             var track = tl.CreateTrack<AlembicTrack>();
    17.             var clip = track.CreateDefaultClip();
    18.             var asset = clip.asset as AlembicShotAsset;
    19.             var go = new GameObject();
    20.             var director = go.AddComponent<PlayableDirector>();
    21.             director.playableAsset = tl;
    22.  
    23.             var asp = UnityEngine.Object.FindObjectOfType<AlembicStreamPlayer>();
    24.             var expo = asset.StreamPlayer;
    25.             expo.exposedName = UnityEditor.GUID.Generate().ToString();
    26.             asset.StreamPlayer = expo;
    27.  
    28.             director.SetReferenceValue(asset.StreamPlayer.exposedName, asp);
    29.         }
    30.     }
    31. }
    I think your bug is around lines 15-17: ExposedReference is a struct and you are setting the exposed name on a local copy.

    Please tell me how it goes.
     
    johhnry likes this.
  3. johhnry

    johhnry

    Joined:
    Jan 7, 2020
    Posts:
    2
    Hi @vladala

    Thank you so much, the thing I was missing was to reassign the StreamPlayer local copy to the original one!

    asset.StreamPlayer = expo;


    It works now ;)