//---------------------------------------------------------------------------------------------------------------------- internal static void LockAndEditPlayableFrame(SISPlayableFrame playableFrame, RenderCachePlayableAsset renderCachePlayableAsset) { int index = playableFrame.GetIndex(); string filePath = renderCachePlayableAsset.GetImageFilePath(index); if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath)) { EditorUtility.DisplayDialog(StreamingImageSequenceConstants.DIALOG_HEADER, "Please update RenderCachePlayableAsset.", "Ok"); return; } string fullPath = Path.GetFullPath(filePath); playableFrame.SetLocked(true); string imageAppPath = EditorPrefs.GetString("kImagesDefaultApp"); if (string.IsNullOrEmpty(imageAppPath) || !File.Exists(imageAppPath)) { System.Diagnostics.Process.Start(fullPath); return; } System.Diagnostics.Process.Start(imageAppPath, fullPath); }
//---------------------------------------------------------------------------------------------------------------------- /// <inheritdoc/> public override void OnClipChanged(TimelineClip clip) { base.OnClipChanged(clip); RenderCachePlayableAsset renderCachePlayableAsset = clip.asset as RenderCachePlayableAsset; Assert.IsNotNull(renderCachePlayableAsset); renderCachePlayableAsset.RefreshPlayableFrames(); }
//---------------------------------------------------------------------------------------------------------------------- /// <inheritdoc/> public override void OnCreate(TimelineClip clip, TrackAsset track, TimelineClip clonedFrom) { RenderCachePlayableAsset asset = clip.asset as RenderCachePlayableAsset; Assert.IsNotNull(asset); RenderCacheClipData sisData = new RenderCacheClipData(clip); asset.BindClipData(sisData); }
static void UpdateRenderCache(ShortcutArguments args) { TimelineClip clip = TimelineEditor.selectedClip; if (null == clip) return; RenderCachePlayableAsset renderCachePlayableAsset = clip.asset as RenderCachePlayableAsset; if (null == renderCachePlayableAsset) return; //Loop time EditorCoroutineUtility.StartCoroutineOwnerless(RenderCachePlayableAssetInspector.UpdateRenderCacheCoroutine(TimelineEditor.inspectedDirector, renderCachePlayableAsset)); }
//---------------------------------------------------------------------------------------------------------------------- void DrawPreviewImage(ref PreviewDrawInfo drawInfo, TimelineClip clip, RenderCachePlayableAsset renderCachePlayableAsset) { double normalizedLocalTime = drawInfo.LocalTime / clip.duration; IList <string> imageFileNames = renderCachePlayableAsset.GetImageFileNames(); Assert.IsNotNull(imageFileNames); int count = imageFileNames.Count; Assert.IsTrue(imageFileNames.Count > 0); int index = Mathf.RoundToInt(count * (float)normalizedLocalTime); index = Mathf.Clamp(index, 0, count - 1); //Load string imagePath = renderCachePlayableAsset.GetImageFilePath(index); if (!File.Exists(imagePath)) { return; } ImageLoader.GetImageDataInto(imagePath, StreamingImageSequenceConstants.IMAGE_TYPE_PREVIEW , out ImageData imageData); switch (imageData.ReadStatus) { case StreamingImageSequenceConstants.READ_STATUS_LOADING: break; case StreamingImageSequenceConstants.READ_STATUS_SUCCESS: { Texture2D tex = PreviewTextureFactory.GetOrCreate(imagePath, ref imageData); if (null != tex) { Graphics.DrawTexture(drawInfo.DrawRect, tex); } break; } default: { ImageLoader.RequestLoadPreviewImage(imagePath, (int)drawInfo.DrawRect.width, (int)drawInfo.DrawRect.height); break; } } }
static void LockAndEditFrame(ShortcutArguments args) { foreach (Object obj in Selection.objects) { FrameMarker frameMarker = obj as FrameMarker; if (null == frameMarker) { continue; } SISPlayableFrame playableFrame = frameMarker.GetOwner(); RenderCachePlayableAsset playableAsset = playableFrame.GetTimelineClipAsset<RenderCachePlayableAsset>(); if (null == playableAsset) return; FrameMarkerInspector.LockAndEditPlayableFrame(playableFrame, playableAsset); } }
public IEnumerator CreatePlayableAsset() { PlayableDirector director = EditorUtilityTest.NewSceneWithDirector(); TimelineClip clip = EditorUtilityTest.CreateTestRenderCacheTimelineClip(director); RenderCachePlayableAsset renderCachePlayableAsset = clip.asset as RenderCachePlayableAsset; Assert.IsNotNull(renderCachePlayableAsset); //Test the track immediately RenderCacheTrack track = clip.GetParentTrack() as RenderCacheTrack; Assert.IsNotNull(track); yield return(null); EditorUtilityTest.DestroyTestTimelineAssets(clip); yield return(null); }
//---------------------------------------------------------------------------------------------------------------------- internal static void LockAndEditPlayableFrame(SISPlayableFrame playableFrame, RenderCachePlayableAsset renderCachePlayableAsset) { int index = playableFrame.GetIndex(); string filePath = renderCachePlayableAsset.GetImageFilePath(index); if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath)) { EditorUtility.DisplayDialog(StreamingImageSequenceConstants.DIALOG_HEADER, "Please update RenderCachePlayableAsset.", "Ok"); return; } playableFrame.SetLocked(true); LaunchImageApplicationExternalTool(Path.GetFullPath(filePath)); }
//---------------------------------------------------------------------------------------------------------------------- /// <inheritdoc/> public override void DrawBackground(TimelineClip clip, ClipBackgroundRegion region) { base.DrawBackground(clip, region); Rect rect = region.position; if (rect.width <= SISEditorConstants.MIN_PREVIEW_REGION_WIDTH) { return; } RenderCachePlayableAsset curAsset = clip.asset as RenderCachePlayableAsset; if (null == curAsset) { return; } IList <string> imageFileNames = curAsset.GetImageFileNames(); if (null == imageFileNames || imageFileNames.Count <= 0) { return; } if (Event.current.type == EventType.Repaint) { PreviewClipInfo clipInfo = new PreviewClipInfo() { Duration = clip.duration, TimeScale = clip.timeScale, ClipIn = clip.clipIn, FramePerSecond = clip.parentTrack.timelineAsset.editorSettings.fps, ImageDimensionRatio = curAsset.GetOrUpdateDimensionRatio(), VisibleLocalStartTime = region.startTime, VisibleLocalEndTime = region.endTime, VisibleRect = rect, }; PreviewUtility.EnumeratePreviewImages(ref clipInfo, (PreviewDrawInfo drawInfo) => { DrawPreviewImage(ref drawInfo, clip, curAsset); }); } }
//---------------------------------------------------------------------------------------------------------------------- public override void OnInspectorGUI() { ShortcutBinding useFrameShortcut = ShortcutManager.instance.GetShortcutBinding(SISEditorConstants.SHORTCUT_TOGGLE_FRAME_MARKER); bool prevUseFrame = m_assets[0].IsFrameUsed(); bool useFrame = EditorGUILayout.Toggle($"Use Frame ({useFrameShortcut})", prevUseFrame); if (useFrame != prevUseFrame) { //Set all selected objects foreach (FrameMarker m in m_assets) { SetMarkerValueByContext(m, useFrame); } } //Only show lock and edit for RenderCachePlayableAsset foreach (FrameMarker frameMarker in m_assets) { SISPlayableFrame playableFrame = frameMarker.GetOwner(); RenderCachePlayableAsset playableAsset = playableFrame.GetTimelineClipAsset <RenderCachePlayableAsset>(); if (null == playableAsset) { return; } } //m_assets only contain RenderCachePlayableAsset at this point ShortcutBinding lockAndEditShortcut = ShortcutManager.instance.GetShortcutBinding(SISEditorConstants.SHORTCUT_LOCK_AND_EDIT_FRAME); if (GUILayout.Button($"Lock and Edit ({lockAndEditShortcut})")) { foreach (FrameMarker frameMarker in m_assets) { SISPlayableFrame playableFrame = frameMarker.GetOwner(); RenderCachePlayableAsset playableAsset = playableFrame.GetTimelineClipAsset <RenderCachePlayableAsset>(); Assert.IsNotNull(playableAsset); LockAndEditPlayableFrame(playableFrame, playableAsset); } } }
//---------------------------------------------------------------------------------------------------------------------- ///<inheritdoc /> public override ActionValidity Validate(IEnumerable <IMarker> markers) { foreach (IMarker marker in markers) { FrameMarker frameMarker = marker as FrameMarker; if (null == frameMarker) { return(ActionValidity.NotApplicable); } SISPlayableFrame playableFrame = frameMarker.GetOwner(); RenderCachePlayableAsset playableAsset = playableFrame.GetTimelineClipAsset <RenderCachePlayableAsset>(); if (null == playableAsset) { return(ActionValidity.NotApplicable); } } return(ActionValidity.Valid); }
///<inheritdoc /> public override bool Execute(IEnumerable <IMarker> markers) { foreach (IMarker marker in markers) { FrameMarker frameMarker = marker as FrameMarker; if (null == frameMarker) { return(false); } SISPlayableFrame playableFrame = frameMarker.GetOwner(); RenderCachePlayableAsset playableAsset = playableFrame.GetTimelineClipAsset <RenderCachePlayableAsset>(); if (null == playableAsset) { return(false); } FrameMarkerInspector.LockAndEditPlayableFrame(playableFrame, playableAsset); } return(true); }
internal static TimelineClip CreateTestRenderCacheTimelineClip(PlayableDirector director) { string tempTimelineAssetPath = AssetDatabase.GenerateUniqueAssetPath("Assets/TempRenderCacheTimelineForTestRunner.playable"); //Create timeline asset TimelineAsset timelineAsset = ScriptableObject.CreateInstance <TimelineAsset>(); director.playableAsset = timelineAsset; AssetDatabase.CreateAsset(timelineAsset, tempTimelineAssetPath); //Create empty asset RenderCacheTrack renderCacheTrack = timelineAsset.CreateTrack <RenderCacheTrack>(null, "Footage"); TimelineClip clip = renderCacheTrack.CreateDefaultClip(); RenderCachePlayableAsset sisAsset = clip.asset as RenderCachePlayableAsset; Assert.IsNotNull(sisAsset); //Select gameObject and open Timeline Window. This will trigger the TimelineWindow's update etc. EditorApplication.ExecuteMenuItem("Window/Sequencing/Timeline"); Selection.activeObject = director; return(clip); }
//---------------------------------------------------------------------------------------------------------------------- public override void OnInspectorGUI() { ShortcutBinding useFrameShortcut = ShortcutManager.instance.GetShortcutBinding(SISEditorConstants.SHORTCUT_TOGGLE_FRAME_MARKER); bool prevUseFrame = m_assets[0].IsFrameUsed(); bool useFrame = EditorGUILayout.Toggle($"Use Frame ({useFrameShortcut})", prevUseFrame); if (useFrame != prevUseFrame) { //Set all selected objects foreach (FrameMarker m in m_assets) { SetMarkerValueByContext(m, useFrame); } } if (1 == m_assets.Length) { SISPlayableFrame playableFrame = m_assets[0].GetOwner(); string prevNote = playableFrame?.GetUserNote(); DrawNoteGUI(prevNote); } else { int numSelectedAssets = m_assets.Length; Assert.IsTrue(numSelectedAssets > 1); SISPlayableFrame firstPlayableFrame = m_assets[0].GetOwner(); //Check invalid PlayableFrame. Perhaps because of unsupported Duplicate operation ? if (null == firstPlayableFrame) { return; } string prevNote = firstPlayableFrame.GetUserNote(); for (int i = 1; i < numSelectedAssets; ++i) { SISPlayableFrame playableFrame = m_assets[i].GetOwner(); if (playableFrame.GetUserNote() != prevNote) { prevNote = "<different notes>"; } } DrawNoteGUI(prevNote); } //Only show lock and edit for RenderCachePlayableAsset //[TODO-Sin: 2020-8-24]: Define capabilities in RenderCachePlayableAsset that defines what is visible foreach (FrameMarker frameMarker in m_assets) { SISPlayableFrame playableFrame = frameMarker.GetOwner(); RenderCachePlayableAsset playableAsset = playableFrame.GetTimelineClipAsset <RenderCachePlayableAsset>(); if (null == playableAsset) { return; } } GUILayout.Space(15); //m_assets only contain RenderCachePlayableAsset at this point ShortcutBinding lockAndEditShortcut = ShortcutManager.instance.GetShortcutBinding(SISEditorConstants.SHORTCUT_LOCK_AND_EDIT_FRAME); if (GUILayout.Button($"Lock and Edit ({lockAndEditShortcut})")) { foreach (FrameMarker frameMarker in m_assets) { SISPlayableFrame playableFrame = frameMarker.GetOwner(); RenderCachePlayableAsset playableAsset = playableFrame.GetTimelineClipAsset <RenderCachePlayableAsset>(); Assert.IsNotNull(playableAsset); LockAndEditPlayableFrame(playableFrame, playableAsset); } } }
//---------------------------------------------------------------------------------------------------------------------- internal static IEnumerator UpdateRenderCacheCoroutine(PlayableDirector director, RenderCachePlayableAsset renderCachePlayableAsset) { Assert.IsNotNull(director); Assert.IsNotNull(renderCachePlayableAsset); TimelineClipSISData timelineClipSISData = renderCachePlayableAsset.GetBoundTimelineClipSISData(); if (null == timelineClipSISData) { EditorUtility.DisplayDialog("Streaming Image Sequence", "RenderCachePlayableAsset is not ready", "Ok"); yield break; } TrackAsset track = renderCachePlayableAsset.GetBoundTimelineClipSISData().GetOwner().parentTrack; BaseRenderCapturer renderCapturer = director.GetGenericBinding(track) as BaseRenderCapturer; if (null == renderCapturer) { EditorUtility.DisplayDialog("Streaming Image Sequence", "Please bind an appropriate RenderCapturer component to the track.", "Ok"); yield break; } //begin capture bool canCapture = renderCapturer.BeginCapture(); if (!canCapture) { EditorUtility.DisplayDialog("Streaming Image Sequence", renderCapturer.GetLastErrorMessage(), "Ok"); yield break; } //Check output folder string outputFolder = renderCachePlayableAsset.GetFolder(); if (string.IsNullOrEmpty(outputFolder) || !Directory.Exists(outputFolder)) { EditorUtility.DisplayDialog("Streaming Image Sequence", "Invalid output folder", "Ok"); yield break; } Texture capturerTex = renderCapturer.GetInternalTexture(); //Show progress in game view GameObject progressGo = new GameObject("Blitter"); LegacyTextureBlitter blitter = progressGo.AddComponent <LegacyTextureBlitter>(); blitter.SetTexture(capturerTex); blitter.SetCameraDepth(int.MaxValue); TimelineClip timelineClip = timelineClipSISData.GetOwner(); double nextDirectorTime = timelineClip.start; double timePerFrame = 1.0f / track.timelineAsset.editorSettings.fps; int fileCounter = 0; int numFiles = (int)Math.Ceiling(timelineClip.duration / timePerFrame) + 1; int numDigits = MathUtility.GetNumDigits(numFiles); string prefix = $"{timelineClip.displayName}_"; List <string> imageFileNames = new List <string>(numFiles); //Store old files that has the same pattern string[] existingFiles = Directory.GetFiles(outputFolder, $"*.png"); HashSet <string> filesToDelete = new HashSet <string>(existingFiles); bool cancelled = false; while (nextDirectorTime <= timelineClip.end && !cancelled) { string fileName = $"{prefix}{fileCounter.ToString($"D{numDigits}")}.png"; string outputFilePath = Path.Combine(outputFolder, fileName); SISPlayableFrame playableFrame = timelineClipSISData.GetPlayableFrame(fileCounter); bool captureFrame = (!timelineClipSISData.AreFrameMarkersRequested() || //if markers are not requested, capture !File.Exists(outputFilePath) || //if file doesn't exist, capture (null != playableFrame && playableFrame.IsUsed() && !playableFrame.IsLocked()) ); if (filesToDelete.Contains(outputFilePath)) { filesToDelete.Remove(outputFilePath); } imageFileNames.Add(fileName); if (captureFrame) { SetDirectorTime(director, nextDirectorTime); //Need at least two frames in order to wait for the TimelineWindow to be updated ? yield return(null); yield return(null); yield return(null); //Unload texture because it may be overwritten StreamingImageSequencePlugin.UnloadImageAndNotify(outputFilePath); renderCapturer.CaptureToFile(outputFilePath); } nextDirectorTime += timePerFrame; ++fileCounter; cancelled = EditorUtility.DisplayCancelableProgressBar( "StreamingImageSequence", "Caching render results", ((float)fileCounter / numFiles)); } if (!cancelled) { renderCachePlayableAsset.SetImageFileNames(imageFileNames); //Delete old files if (AssetDatabase.IsValidFolder(outputFolder)) { foreach (string oldFile in filesToDelete) { AssetDatabase.DeleteAsset(oldFile); } } else { foreach (string oldFile in filesToDelete) { File.Delete(oldFile); } } } //Notify FolderContentsChangedNotifier.GetInstance().Notify(outputFolder); //Cleanup EditorUtility.ClearProgressBar(); renderCapturer.EndCapture(); ObjectUtility.Destroy(progressGo); AssetDatabase.Refresh(); yield return(null); }
public IEnumerator UpdateRenderCachePNGInStreamingAssets() { PlayableDirector director = EditorUtilityTest.NewSceneWithDirector(); TimelineClip clip = EditorUtilityTest.CreateTestRenderCacheTimelineClip(director); TimelineAsset timelineAsset = director.playableAsset as TimelineAsset; RenderCachePlayableAsset renderCachePlayableAsset = clip.asset as RenderCachePlayableAsset; RenderCacheTrack track = clip.GetParentTrack() as RenderCacheTrack; Assert.IsNotNull(timelineAsset); Assert.IsNotNull(renderCachePlayableAsset); Assert.IsNotNull(track); Assert.IsNotNull(Camera.main); yield return(null); clip.duration = (1.0f / timelineAsset.editorSettings.GetFPS()); const string OUTPUT_FOLDER = "Asset/StreamingAssets/RenderCachePNGForTestRunner"; Directory.CreateDirectory(OUTPUT_FOLDER); renderCachePlayableAsset.SetFolder(OUTPUT_FOLDER); GameObject cameraRenderCapturerGO = new GameObject(); CameraRenderCapturer cameraRenderCapturer = cameraRenderCapturerGO.AddComponent <CameraRenderCapturer>(); cameraRenderCapturer.SetCamera(Camera.main); director.SetGenericBinding(track, cameraRenderCapturer); yield return(null); //Update RenderCache EditorCoroutineUtility.StartCoroutineOwnerless( RenderCachePlayableAssetInspector.UpdateRenderCacheCoroutine(director, renderCachePlayableAsset) ); //A hack to wait until the coroutine is finished const float TIMEOUT_SEC = 3.0f; Assert.IsTrue(Directory.Exists(OUTPUT_FOLDER)); float prevTime = Time.realtimeSinceStartup; while (Time.realtimeSinceStartup - prevTime < TIMEOUT_SEC) { yield return(null); } string imageFilePath = renderCachePlayableAsset.GetImageFilePath(0); Assert.IsTrue(File.Exists(imageFilePath)); ImageLoader.RequestLoadFullImage(imageFilePath); //Another hack to wait until the load is finished prevTime = Time.realtimeSinceStartup; while (Time.realtimeSinceStartup - prevTime < TIMEOUT_SEC) { yield return(null); } ImageLoader.GetImageDataInto(imageFilePath, StreamingImageSequenceConstants.IMAGE_TYPE_FULL, out ImageData imageData); Assert.AreEqual(StreamingImageSequenceConstants.READ_STATUS_SUCCESS, imageData.ReadStatus); yield return(null); //cleanup StreamingImageSequencePlugin.UnloadAllImages(); bool folderDeleted = FileUtility.DeleteFilesAndFolders(OUTPUT_FOLDER); Assert.IsTrue(folderDeleted); EditorUtilityTest.DestroyTestTimelineAssets(clip); yield return(null); }
//---------------------------------------------------------------------------------------------------------------------- internal static IEnumerator UpdateRenderCacheCoroutine(PlayableDirector director, RenderCachePlayableAsset renderCachePlayableAsset) { Assert.IsNotNull(director); Assert.IsNotNull(renderCachePlayableAsset); PlayableFrameClipData clipData = renderCachePlayableAsset.GetBoundClipData(); if (null == clipData) { EditorUtility.DisplayDialog("Streaming Image Sequence", "RenderCachePlayableAsset is not ready", "Ok"); yield break; } TrackAsset track = renderCachePlayableAsset.GetBoundClipData().GetOwner().GetParentTrack(); BaseRenderCapturer renderCapturer = director.GetGenericBinding(track) as BaseRenderCapturer; if (null == renderCapturer) { EditorUtility.DisplayDialog("Streaming Image Sequence", "Please bind an appropriate RenderCapturer component to the track.", "Ok"); yield break; } //Check output folder string outputFolder = renderCachePlayableAsset.GetFolder(); if (string.IsNullOrEmpty(outputFolder) || !Directory.Exists(outputFolder)) { EditorUtility.DisplayDialog("Streaming Image Sequence", "Invalid output folder", "Ok"); yield break; } //Check if we can capture bool canCapture = renderCapturer.CanCaptureV(); if (!canCapture) { EditorUtility.DisplayDialog("Streaming Image Sequence", renderCapturer.GetLastErrorMessage(), "Ok"); yield break; } //begin capture IEnumerator beginCapture = renderCapturer.BeginCaptureV(); while (beginCapture.MoveNext()) { yield return(beginCapture.Current); } //Show progress in game view Texture capturerTex = renderCapturer.GetInternalTexture(); RenderCachePlayableAssetEditorConfig editorConfig = renderCachePlayableAsset.GetEditorConfig(); BaseTextureBlitter blitter = CreateBlitter(capturerTex); Material blitToScreenMat = renderCapturer.GetOrCreateBlitToScreenEditorMaterialV(); if (!blitToScreenMat.IsNullRef()) { blitToScreenMat.SetColor(m_bgColorProperty, editorConfig.GetUpdateBGColor()); blitter.SetBlitMaterial(blitToScreenMat); } GameObject blitterGO = blitter.gameObject; TimelineClip timelineClip = clipData.GetOwner(); double timePerFrame = 1.0f / track.timelineAsset.editorSettings.GetFPS(); //initial calculation of loop vars bool captureAllFrames = editorConfig.GetCaptureAllFrames(); int fileCounter = 0; int numFiles = (int)Math.Ceiling(timelineClip.duration / timePerFrame) + 1; int numDigits = MathUtility.GetNumDigits(numFiles); if (!captureAllFrames) { fileCounter = editorConfig.GetCaptureStartFrame(); numFiles = (editorConfig.GetCaptureEndFrame() - fileCounter) + 1; if (numFiles <= 0) { EditorUtility.DisplayDialog("Streaming Image Sequence", "Invalid Start/End Frame Settings", "Ok"); yield break; } } int captureStartFrame = fileCounter; string prefix = $"{timelineClip.displayName}_"; List <WatchedFileInfo> imageFiles = new List <WatchedFileInfo>(numFiles); //Store old files that has the same pattern string[] existingFiles = Directory.GetFiles(outputFolder, $"*.png"); HashSet <string> filesToDelete = new HashSet <string>(existingFiles); RenderCacheOutputFormat outputFormat = renderCachePlayableAsset.GetOutputFormat(); string outputExt = null; switch (outputFormat) { case RenderCacheOutputFormat.EXR: outputExt = "exr"; break; default: outputExt = "png"; break;; } bool cancelled = false; while (!cancelled) { //Always recalculate from start to avoid floating point errors double directorTime = timelineClip.start + (fileCounter * timePerFrame); if (directorTime > timelineClip.end) { break; } if (!captureAllFrames && fileCounter > editorConfig.GetCaptureEndFrame()) { break; } string fileName = $"{prefix}{fileCounter.ToString($"D{numDigits}")}.{outputExt}"; string outputFilePath = Path.Combine(outputFolder, fileName); SISPlayableFrame playableFrame = clipData.GetPlayableFrame(fileCounter); bool captureFrame = (!clipData.AreFrameMarkersRequested() || //if markers are not requested, capture !File.Exists(outputFilePath) || //if file doesn't exist, capture (null != playableFrame && playableFrame.IsUsed() && !playableFrame.IsLocked()) ); if (filesToDelete.Contains(outputFilePath)) { filesToDelete.Remove(outputFilePath); } if (captureFrame) { SetDirectorTime(director, directorTime); //Need at least two frames in order to wait for the TimelineWindow to be updated ? yield return(null); yield return(null); yield return(null); //Unload texture because it may be overwritten StreamingImageSequencePlugin.UnloadImageAndNotify(outputFilePath); renderCapturer.CaptureToFile(outputFilePath, outputFormat); } Assert.IsTrue(File.Exists(outputFilePath)); FileInfo fileInfo = new FileInfo(outputFilePath); imageFiles.Add(new WatchedFileInfo(fileName, fileInfo.Length)); ++fileCounter; cancelled = EditorUtility.DisplayCancelableProgressBar( "StreamingImageSequence", "Caching render results", ((float)(fileCounter - captureStartFrame) / numFiles)); } if (!cancelled) { //Delete old files if (AssetDatabase.IsValidFolder(outputFolder)) { foreach (string oldFile in filesToDelete) { AssetDatabase.DeleteAsset(oldFile); } } else { foreach (string oldFile in filesToDelete) { File.Delete(oldFile); } } } //Notify FolderContentsChangedNotifier.GetInstance().Notify(outputFolder); //Cleanup EditorUtility.ClearProgressBar(); renderCapturer.EndCaptureV(); ObjectUtility.Destroy(blitterGO); AssetDatabase.Refresh(); renderCachePlayableAsset.Reload();; yield return(null); }