public void BuildPlaybackPrefab(ProgressBar progress) { var timeline = ScriptableObject.CreateInstance <TimelineAsset>(); var animationTrack = timeline.CreateTrack <AnimationTrack>(null, "Playback Animation"); var clip = generateCompressedClip(progress); var playableAsset = ScriptableObject.CreateInstance <AnimationPlayableAsset>(); playableAsset.clip = clip; playableAsset.hideFlags = HideFlags.HideInInspector | HideFlags.HideInHierarchy; playableAsset.name = "Recorded Animation"; var timelineClip = animationTrack.CreateClip(clip); timelineClip.duration = clip.length; timelineClip.asset = playableAsset; timelineClip.displayName = "Recorded Animation"; //If a clip is not recordable, it will not show up as editable in the timeline view. //For whatever reason unity decided that imported clips are not recordable, so we hack a //private variable to force them to be! This seems to have no ill effects but if things go //wrong we can just revert this line timelineClip.GetType().GetField("m_Recordable", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).SetValue(timelineClip, true); //Try to generate a leap recording if we have leap data RecordingTrack recordingTrack = null; LeapRecording leapRecording = null; string framesPath = Path.Combine(dataFolder.Path, "Frames.data"); if (File.Exists(framesPath)) { List <Frame> frames = new List <Frame>(); progress.Begin(1, "Loading Leap Data", "", () => { progress.Step(); using (var reader = File.OpenText(framesPath)) { while (true) { string line = reader.ReadLine(); if (string.IsNullOrEmpty(line)) { break; } frames.Add(JsonUtility.FromJson <Frame>(line)); } } }); leapRecording = ScriptableObject.CreateInstance(_leapRecordingType) as LeapRecording; if (leapRecording != null) { leapRecording.name = "Recorded Leap Data"; leapRecording.LoadFrames(frames); } else { Debug.LogError("Unable to create Leap recording: Invalid type specification for " + "LeapRecording implementation.", this); } } string assetPath = Path.Combine(assetFolder.Path, recordingName + ".asset"); AssetDatabase.CreateAsset(timeline, assetPath); AssetDatabase.AddObjectToAsset(playableAsset, timeline); AssetDatabase.AddObjectToAsset(animationTrack, timeline); AssetDatabase.AddObjectToAsset(clip, timeline); //If we do have a leap recording, create a recording track to house it if (leapRecording != null) { recordingTrack = timeline.CreateTrack <RecordingTrack>(null, "Leap Recording"); var recordingClip = recordingTrack.CreateDefaultClip(); recordingClip.duration = leapRecording.length; var recordingAsset = recordingClip.asset as RecordingClip; recordingAsset.recording = leapRecording; AssetDatabase.AddObjectToAsset(leapRecording, timeline); } AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); //Create the playable director and link it to the new timeline var director = gameObject.AddComponent <PlayableDirector>(); director.playableAsset = timeline; //Create the animator gameObject.AddComponent <Animator>(); //Link the animation track to the animator //(it likes to point to gameobject instead of the animator directly) director.SetGenericBinding(animationTrack.outputs.Query().First().sourceObject, gameObject); //Destroy existing provider var provider = gameObject.GetComponentInChildren <LeapProvider>(); if (provider != null) { GameObject providerObj = provider.gameObject; DestroyImmediate(provider); //If a leap recording track exists, spawn a playable provider and link it to the track if (recordingTrack != null) { var playableProvider = providerObj.AddComponent <LeapPlayableProvider>(); director.SetGenericBinding(recordingTrack.outputs.Query().First().sourceObject, playableProvider); } } buildAudioTracks(progress, director, timeline); buildMethodRecordingTracks(progress, director, timeline); progress.Begin(1, "", "Finalizing Prefab", () => { GameObject myGameObject = gameObject; DestroyImmediate(this); string prefabPath = Path.Combine(assetFolder.Path, recordingName + ".prefab"); PrefabUtility.SaveAsPrefabAsset(myGameObject, prefabPath.Replace('\\', '/')); }); }
public void BuildPlaybackPrefab(ProgressBar progress) { var timeline = ScriptableObject.CreateInstance <TimelineAsset>(); var animationTrack = timeline.CreateTrack <AnimationTrack>(null, "Playback Animation"); var clip = generateCompressedClip(progress); var timelineClip = animationTrack.CreateClip(clip); timelineClip.duration = clip.length; timelineClip.asset = clip; timelineClip.underlyingAsset = clip; //Try to generate a leap recording if we have leap data RecordingTrack recordingTrack = null; LeapRecording leapRecording = null; if (leapData.Count > 0) { leapRecording = ScriptableObject.CreateInstance(_leapRecordingType) as LeapRecording; if (leapRecording != null) { leapRecording.LoadFrames(leapData); } else { Debug.LogError("Unable to create Leap recording: Invalid type specification for " + "LeapRecording implementation.", this); } } string assetPath = Path.Combine(assetFolder.Path, recordingName + ".asset"); AssetDatabase.CreateAsset(timeline, assetPath); AssetDatabase.AddObjectToAsset(animationTrack, timeline); AssetDatabase.AddObjectToAsset(clip, timeline); //If we do have a leap recording, create a recording track to house it if (leapRecording != null) { recordingTrack = timeline.CreateTrack <RecordingTrack>(null, "Leap Recording"); var recordingClip = recordingTrack.CreateDefaultClip(); recordingClip.duration = leapRecording.length; var recordingAsset = recordingClip.asset as RecordingClip; recordingAsset.recording = leapRecording; AssetDatabase.AddObjectToAsset(leapRecording, timeline); } AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); foreach (var recording in GetComponentsInChildren <RecordedData>(includeInactive: true)) { DestroyImmediate(recording); } //Create the playable director and link it to the new timeline var director = gameObject.AddComponent <PlayableDirector>(); director.playableAsset = timeline; //Create the animator and link it to the animation track var animator = gameObject.AddComponent <Animator>(); director.SetGenericBinding(animationTrack.outputs.Query().First().sourceObject, animator); //Destroy existing provider var provider = gameObject.GetComponentInChildren <LeapProvider>(); if (provider != null) { GameObject providerObj = provider.gameObject; DestroyImmediate(provider); //If a leap recording track exists, spawn a playable provider and link it to the track if (recordingTrack != null) { var playableProvider = providerObj.AddComponent <LeapPlayableProvider>(); director.SetGenericBinding(recordingTrack.outputs.Query().First().sourceObject, playableProvider); } } buildAudioTracks(progress, director, timeline); progress.Begin(1, "", "Finalizing Prefab", () => { GameObject myGameObject = gameObject; DestroyImmediate(this); string prefabPath = Path.Combine(assetFolder.Path, recordingName + ".prefab"); PrefabUtility.CreatePrefab(prefabPath.Replace('\\', '/'), myGameObject); }); }