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

replace Cinemachine Shot in timeline during runtime

Discussion in 'Timeline' started by Doronn, Jun 29, 2019.

  1. Doronn

    Doronn

    Joined:
    Sep 17, 2018
    Posts:
    8
    Hi.
    I'm trying to make a timeline sequence which can change in some situations (the change is decided before the sequence starts playing)

    Specifically replace a virtual camera in one of the shots clip.

    But I am not able to figure out how to replace my CinemachineShot clip in the Cinemachine track.

    I tried to simply apply a different virtual camera by code, it worked but the clip got broken and the virtual camera properties in that shot were not applied. when the timeline plays it ignores the clip altogether as if in that point there is no virtual camera active at all.

    Any help about this would be appreciated.

    Edit:
    this is the code for I tested with:
    Code (CSharp):
    1. public static void ReplaceClipCinemachineCamera(this PlayableDirector playableDirector,
    2.             string trackName,
    3.             string clipName,
    4.             GameObject otherVirtualCamera)
    5.         {
    6.             TimelineAsset timeline = playableDirector.playableAsset as TimelineAsset;
    7.  
    8.             if (timeline == null)
    9.             {
    10.                 return;
    11.             }
    12.  
    13.             foreach (var trackAsset in timeline.GetOutputTracks())
    14.             {
    15.                 if (trackAsset.name == trackName)
    16.                 {
    17.                     var clipToEdit = trackAsset.GetClips()
    18.                         .FirstOrDefault(clip => clip.displayName == clipName);
    19.                     if (clipToEdit == null)
    20.                     {
    21.                         continue;
    22.                     }
    23.  
    24.                     var controlPlayableAsset = (clipToEdit.asset as CinemachineShot);
    25.  
    26.                     if (controlPlayableAsset == null)
    27.                     {
    28.                         return;
    29.                     }
    30.  
    31.                     playableDirector.SetReferenceValue(controlPlayableAsset.VirtualCamera.exposedName, otherVirtualCamera);
    32.                 }
    33.             }
    34.         }
     
    Last edited: Jun 29, 2019
  2. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    That looks like it should work. The only thing I can think of is if the timeline is already playing, then this will have no effect. You would need to call playableDirector.RebuildGraph() in that case.
     
  3. Doronn

    Doronn

    Joined:
    Sep 17, 2018
    Posts:
    8
    litterNum123 likes this.
  4. Jiaquarium

    Jiaquarium

    Joined:
    Mar 22, 2020
    Posts:
    45
    Using your code and not filtering on clip name, the below worked for me. Although, this will make every Cinemachine Shot in the timeline update for the specified Virtual Camera.

    Code (CSharp):
    1.        
    2.         private TimelineAsset timeline;
    3.         private CinemachineVirtualCamera virtualCamera;
    4.  
    5.         foreach (var track in timeline.GetOutputTracks())
    6.         {
    7.             var clips = track.GetClips();
    8.  
    9.             foreach (TimelineClip clip in clips)
    10.             {
    11.                 var shot = clip.asset as CinemachineShot;
    12.                
    13.                 if (shot == null)
    14.                     continue;
    15.                
    16.                 director.SetReferenceValue(shot.VirtualCamera.exposedName, virtualCamera);
    17.             }
    18.         }
    19.