//---------------------------------------------------------------------------------------------------------------------- /// <inheritdoc/> public override void OnCreate(TimelineClip clip, TrackAsset track, TimelineClip clonedFrom) { StreamingImageSequencePlayableAsset asset = clip.asset as StreamingImageSequencePlayableAsset; if (null == asset) { Debug.LogError("Asset is not a StreamingImageSequencePlayableAsset: " + clip.asset); return; } StreamingImageSequenceTrack sisTrack = track as StreamingImageSequenceTrack; Assert.IsNotNull(sisTrack); //This callback occurs before the clip is assigned to the track, but we need the track for creating curves. clip.parentTrack = track; //If we have a default asset, and clonedFrom is NULL, which means this is created by user interaction, //such as Folder D&D UnityEditor.DefaultAsset timelineDefaultAsset = asset.GetTimelineDefaultAsset(); if (null != timelineDefaultAsset && null == clonedFrom) { InitializeAssetFromDefaultAsset(asset, timelineDefaultAsset); } //If the clip already has curves (because of cloning, etc), then we don't set anything if (null == clip.curves) { if (asset.HasImages()) { clip.duration = asset.GetImageFileNames().Count * 0.125; // 8fps (standard limited animation) clip.displayName = Path.GetFileName(asset.GetFolder()); } clip.CreateCurves("Curves: " + clip.displayName); } TimelineClipSISData sisData = null; asset.InitTimelineClipCurve(clip); if (null == clonedFrom) { sisData = new TimelineClipSISData(clip); asset.BindTimelineClipSISData(sisData); return; } //Duplicate/Split process StreamingImageSequencePlayableAsset clonedFromAsset = clonedFrom.asset as StreamingImageSequencePlayableAsset; Assert.IsNotNull(clonedFromAsset); TimelineClipSISData otherSISData = clonedFromAsset.GetBoundTimelineClipSISData(); sisData = new TimelineClipSISData(clip, otherSISData); asset.BindTimelineClipSISData(sisData); clip.displayName = clonedFrom.displayName + " (Cloned)"; }
public IEnumerator CreatePlayableAsset() { PlayableDirector director = EditorUtilityTest.NewSceneWithDirector(); TimelineClip clip = EditorUtilityTest.CreateTestSISTimelineClip(director); StreamingImageSequencePlayableAsset sisAsset = clip.asset as StreamingImageSequencePlayableAsset; Assert.IsNotNull(sisAsset); //Test the track immediately StreamingImageSequenceTrack track = clip.GetParentTrack() as StreamingImageSequenceTrack; Assert.IsNotNull(track); Assert.IsNotNull(track.GetActivePlayableAsset()); yield return(null); int numImages = sisAsset.GetNumImages(); Assert.IsTrue(numImages > 0); //Test that there should be no active PlayableAsset at the time above what exists in the track. director.time = clip.start + clip.duration + 1; yield return(null); Assert.IsNull(track.GetActivePlayableAsset()); EditorUtilityTest.DestroyTestTimelineAssets(clip); yield return(null); }
//---------------------------------------------------------------------------------------------------------------------- /// <inheritdoc/> public override ClipDrawOptions GetClipOptions(TimelineClip clip) { ClipDrawOptions clipOptions = base.GetClipOptions(clip); StreamingImageSequencePlayableAsset asset = clip.asset as StreamingImageSequencePlayableAsset; if (null == asset) { Debug.LogError("Asset is not a StreamingImageSequencePlayableAsset: " + clip.asset); return(clipOptions); } string folder = asset.GetFolder(); if (string.IsNullOrEmpty(folder)) { clipOptions.errorText = NO_FOLDER_ASSIGNED_ERROR; } else if (!Directory.Exists(folder)) { clipOptions.errorText = FOLDER_MISSING_ERROR; } else if (asset.GetNumImages() <= 0) { clipOptions.errorText = NO_PICTURES_ASSIGNED_ERROR; } clipOptions.tooltip = folder; #if AT_USE_TIMELINE_GE_1_6_0 clipOptions.hideScaleIndicator = true; #endif return(clipOptions); }
//---------------------------------------------------------------------------------------------------------------------- public void Execute() { //Only continue preloading images when we are not in play mode if (Application.isPlaying) { return; } Assert.IsNotNull(m_mixer); var clipAssets = m_mixer.GetClipAssets(); bool needsRefresh = false; foreach (KeyValuePair <TimelineClip, StreamingImageSequencePlayableAsset> kv in clipAssets) { StreamingImageSequencePlayableAsset sisAsset = kv.Value; sisAsset.ContinuePreloadingImages(); if (sisAsset.UpdateTextureWithRequestedImage()) { needsRefresh = true; } } if (needsRefresh) { TimelineEditor.Refresh(RefreshReason.ContentsModified); } }
public IEnumerator ShowFrameMarkers() { PlayableDirector director = EditorUtilityTest.NewSceneWithDirector(); TimelineClip clip = EditorUtilityTest.CreateTestTimelineClip(director); StreamingImageSequencePlayableAsset sisAsset = clip.asset as StreamingImageSequencePlayableAsset; Assert.IsNotNull(sisAsset); yield return(null); //Show TimelineClipSISData timelineClipSISData = sisAsset.GetBoundTimelineClipSISData(); TrackAsset trackAsset = clip.parentTrack; timelineClipSISData.RequestFrameMarkers(true, true); TimelineEditor.Refresh(RefreshReason.ContentsModified); yield return(null); Assert.AreEqual(TimelineUtility.CalculateNumFrames(clip), trackAsset.GetMarkerCount()); yield return(null); //Undo showing FrameMarkers EditorUtilityTest.UndoAndRefreshTimelineEditor(); yield return(null); Assert.False(timelineClipSISData.AreFrameMarkersRequested()); Assert.AreEqual(0, trackAsset.GetMarkerCount()); EditorUtilityTest.DestroyTestTimelineAssets(clip); yield return(null); }
//---------------------------------------------------------------------------------------------------------------------- internal static TimelineClip CreateTestSISTimelineClip(PlayableDirector director) { string tempTimelineAssetPath = AssetDatabase.GenerateUniqueAssetPath("Assets/TempSISTimelineForTestRunner.playable"); //Create timeline asset TimelineAsset timelineAsset = ScriptableObject.CreateInstance <TimelineAsset>(); director.playableAsset = timelineAsset; AssetDatabase.CreateAsset(timelineAsset, tempTimelineAssetPath); //Create empty asset StreamingImageSequenceTrack sisTrack = timelineAsset.CreateTrack <StreamingImageSequenceTrack>(null, "SIS Track"); TimelineClip clip = sisTrack.CreateDefaultClip(); StreamingImageSequencePlayableAsset sisAsset = clip.asset as StreamingImageSequencePlayableAsset; Assert.IsNotNull(sisAsset); //Select gameObject and open Timeline Window. This will trigger the TimelineWindow's update etc. EditorApplication.ExecuteMenuItem("Window/Sequencing/Timeline"); // Selection.activeTransform = director.gameObject.transform; // TimelineEditor.selectedClip = sisAsset.GetBoundTimelineClip(); Selection.activeObject = director; string fullPath = Path.GetFullPath(SRC_IMAGE_PATH); ImageSequenceImporter.ImportImages(fullPath, sisAsset, false); return(clip); }
//---------------------------------------------------------------------------------------------------------------------- /// <inheritdoc/> public override ClipDrawOptions GetClipOptions(TimelineClip clip) { var clipOptions = base.GetClipOptions(clip); StreamingImageSequencePlayableAsset asset = clip.asset as StreamingImageSequencePlayableAsset; if (null == asset) { Debug.LogError("Asset is not a StreamingImageSequencePlayableAsset: " + clip.asset); return(clipOptions); } string folder = asset.GetFolder(); if (string.IsNullOrEmpty(folder)) { clipOptions.errorText = NO_FOLDER_ASSIGNED_ERROR; } else if (!Directory.Exists(folder)) { clipOptions.errorText = FOLDER_MISSING_ERROR; } else if (asset.GetImageFileNames() == null) { clipOptions.errorText = NO_PICTURES_ASSIGNED_ERROR; } clipOptions.tooltip = folder; return(clipOptions); }
//---------------------------------------------------------------------------------------------------------------------- void DrawPreviewImage(ref PreviewDrawInfo drawInfo, TimelineClip clip, StreamingImageSequencePlayableAsset sisAsset) { int imageIndex = sisAsset.LocalTimeToImageIndex(clip, drawInfo.LocalTime); IList <string> imageFileNames = sisAsset.GetImageFileNames(); //Load string imagePath = sisAsset.GetImageFilePath(imageIndex); ImageLoader.GetImageDataInto(imagePath, StreamingImageSequenceConstants.IMAGE_TYPE_PREVIEW , out ImageData readResult); switch (readResult.ReadStatus) { case StreamingImageSequenceConstants.READ_STATUS_LOADING: break; case StreamingImageSequenceConstants.READ_STATUS_SUCCESS: { Texture2D tex = PreviewTextureFactory.GetOrCreate(imagePath, ref readResult); if (null != tex) { Graphics.DrawTexture(drawInfo.DrawRect, tex); } break; } default: { ImageLoader.RequestLoadPreviewImage(imagePath, (int)drawInfo.DrawRect.width, (int)drawInfo.DrawRect.height); break; } } }
//---------------------------------------------------------------------------------------------------------------------- private static void InitializeAssetFromDefaultAsset(StreamingImageSequencePlayableAsset playableAsset, UnityEditor.DefaultAsset timelineDefaultAsset) { string path = AssetDatabase.GetAssetPath(timelineDefaultAsset).Replace("\\", "/"); const bool ASK_TO_COPY = false; ImageSequenceImporter.ImportImages(path, playableAsset, ASK_TO_COPY); }
//---------------------------------------------------------------------------------------------------------------------- /// <inheritdoc/> public override void OnClipChanged(TimelineClip clip) { base.OnClipChanged(clip); StreamingImageSequencePlayableAsset sisAsset = clip.asset as StreamingImageSequencePlayableAsset; Assert.IsNotNull(sisAsset); sisAsset.RefreshPlayableFrames(); }
//--------------------------------------------------------------------------------------------------------------------- private static StreamingImageSequencePlayableAsset CreateUniqueSISAsset(string playableAssetPath) { StreamingImageSequencePlayableAsset playableAsset = ScriptableObject.CreateInstance <StreamingImageSequencePlayableAsset>(); string uniquePath = AssetDatabase.GenerateUniqueAssetPath(playableAssetPath); AssetDatabase.CreateAsset(playableAsset, uniquePath); return(playableAsset); }
// public GUIStyle m_style; public BGJobCacheParam(StreamingImageSequencePlayableAsset asset) { m_asset = asset; m_collorArray = new UInt32[m_asset.Pictures.Length]; m_tex2D = new Texture2D(m_asset.Pictures.Length, 1); m_allLoaded = false; // m_style = new GUIStyle(GUI.skin.box); }
private static void ProcessMovieProxyTrack(MovieProxyTrack track) { foreach (var clip in track.GetClips()) { // You might want to use "as" rather than compare type. // "as" sometimes fail on first importing time for project. if (clip.asset.GetType() != typeof(StreamingImageSequencePlayableAsset)) { Debug.LogError("StreamingImageSequencePlayableAsset is broken:" + clip.asset.name); continue; } /* * if (clip.asset == null) * { * Debug.LogError("StreamingImageSequencePlayableAsset on " + clip.displayName + " is broken."); * continue; * }*/ StreamingImageSequencePlayableAsset asset = (StreamingImageSequencePlayableAsset)clip.asset; if (null == asset.Pictures) { continue; } int length = asset.Pictures.Length; if (m_MovieProxyPlayableAssetToColorArray.ContainsKey(asset)) { } else { m_MovieProxyPlayableAssetToColorArray.Add(asset, new BGJobCacheParam(asset)); } var param = m_MovieProxyPlayableAssetToColorArray[asset]; int allAreLoaded = PluginUtil.GetAllAreLoaded(asset.GetInstanceID()); if (allAreLoaded == 0) { new BGJobCacheChecker(m_MovieProxyPlayableAssetToColorArray[asset]); UInt32[] colorArray = m_MovieProxyPlayableAssetToColorArray[asset].m_collorArray; if (colorArray == null) { return; } PluginUtil.SetOverwrapWindowData(asset.GetInstanceID(), colorArray, colorArray.Length); if (param.m_allLoaded) { PluginUtil.SetAllAreLoaded(asset.GetInstanceID(), 1); } } else { PluginUtil.HideOverwrapWindow(asset.GetInstanceID()); } } }
//---------------------------------------------------------------------------------------------------------------------- protected override void DrawPreviewImageV(ref PreviewDrawInfo drawInfo, TimelineClip clip, ImageFolderPlayableAsset <SISClipData> playableAsset) { StreamingImageSequencePlayableAsset sisAsset = playableAsset as StreamingImageSequencePlayableAsset; Assert.IsNotNull(sisAsset); int imageIndex = sisAsset.LocalTimeToImageIndex(clip, drawInfo.LocalTime); string imagePath = sisAsset.GetImageFilePath(imageIndex); PreviewUtility.DrawPreviewImage(ref drawInfo, imagePath); }
public void Import() { EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects); string fullPath = "Packages/com.unity.streaming-image-sequence/Tests/Data/AeConvert.jstimeline"; Assert.IsTrue(File.Exists(fullPath)); string destFolder = "TestRunner"; JstimelineImporter.ImportTimeline(fullPath, destFolder); //Check if the generated director is valid PlayableDirector[] directors = Object.FindObjectsOfType <PlayableDirector>(); Assert.AreEqual(1, directors.Length); PlayableDirector pd = directors[0]; TimelineAsset timelineAsset = pd.playableAsset as TimelineAsset; Assert.IsNotNull(timelineAsset); Assert.AreEqual(timelineAsset.outputTrackCount, 1); foreach (TrackAsset trackAsset in timelineAsset.GetOutputTracks()) { StreamingImageSequenceTrack imageSequenceTrack = trackAsset as StreamingImageSequenceTrack; Assert.IsNotNull(imageSequenceTrack); foreach (TimelineClip clip in imageSequenceTrack.GetClips()) { Assert.IsNotNull(clip.asset); StreamingImageSequencePlayableAsset playableAsset = clip.asset as StreamingImageSequencePlayableAsset; Assert.IsNotNull(playableAsset); Assert.AreEqual(10, playableAsset.GetImageFileNames().Count); } //Make sure a StreamingImageSequenceRenderer is bound to the trackAsset StreamingImageSequenceRenderer r = pd.GetGenericBinding(trackAsset) as StreamingImageSequenceRenderer; Assert.IsNotNull(r); } //Delete created assets string destAssetsFolder = "Assets/" + destFolder; string[] createdAssets = AssetDatabase.FindAssets("", new[] { destAssetsFolder }); Assert.Greater(createdAssets.Length, 0); foreach (string guid in createdAssets) { string assetPath = AssetDatabase.GUIDToAssetPath(guid); AssetDatabase.DeleteAsset(assetPath); } Directory.Delete(destAssetsFolder); }
public IEnumerator ResizePlayableAsset() { PlayableDirector director = EditorUtilityTest.NewSceneWithDirector(); TimelineClip clip = EditorUtilityTest.CreateTestSISTimelineClip(director); StreamingImageSequencePlayableAsset sisAsset = clip.asset as StreamingImageSequencePlayableAsset; Assert.IsNotNull(sisAsset); yield return(null); SISClipData clipData = sisAsset.GetBoundClipData(); Assert.IsNotNull(clipData); clipData.RequestFrameMarkers(true, true); Undo.IncrementCurrentGroup(); //the base of undo is here. FrameMarkerVisibility is still true after undo TimelineEditor.Refresh(RefreshReason.ContentsModified); yield return(null); //Original length TrackAsset trackAsset = clip.GetParentTrack(); Assert.AreEqual(TimelineUtility.CalculateNumFrames(clip), trackAsset.GetMarkerCount()); double origClipDuration = clip.duration; //Resize longer EditorUtilityTest.ResizeSISTimelineClip(clip, origClipDuration + 3.0f); yield return(null); Assert.AreEqual(TimelineUtility.CalculateNumFrames(clip), trackAsset.GetMarkerCount()); //Undo EditorUtilityTest.UndoAndRefreshTimelineEditor(); yield return(null); Assert.AreEqual(origClipDuration, clip.duration); Assert.AreEqual(TimelineUtility.CalculateNumFrames(clip), trackAsset.GetMarkerCount()); //Resize shorter EditorUtilityTest.ResizeSISTimelineClip(clip, Mathf.Max(0.1f, ((float)(origClipDuration) - 3.0f))); yield return(null); Assert.AreEqual(TimelineUtility.CalculateNumFrames(clip), trackAsset.GetMarkerCount()); //Undo EditorUtilityTest.UndoAndRefreshTimelineEditor(); yield return(null); Assert.AreEqual(origClipDuration, clip.duration); Assert.AreEqual(TimelineUtility.CalculateNumFrames(clip), trackAsset.GetMarkerCount()); EditorUtilityTest.DestroyTestTimelineAssets(clip); yield return(null); }
//--------------------------------------------------------------------------------------------------------------------- //Path can point to a file or a folder. //If it points to a file, then the folder will be automatically detected private static void FindFolderAndImages(string path, out string folder, out List <WatchedFileInfo> imageFiles) { Assert.IsFalse(string.IsNullOrEmpty(path)); //Convert path to folder here folder = path; FileAttributes attr = File.GetAttributes(path); if (!attr.HasFlag(FileAttributes.Directory)) { folder = Path.GetDirectoryName(folder); } imageFiles = WatchedFileInfo.FindFiles(folder, StreamingImageSequencePlayableAsset.GetSupportedImageFilePatterns() ); }
//---------------------------------------------------------------------------------------------------------------------- /// <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; } StreamingImageSequencePlayableAsset curAsset = clip.asset as StreamingImageSequencePlayableAsset; if (null == curAsset || !curAsset.HasImages()) { 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); }); //For hiding frame marker automatically int numFrames = Mathf.RoundToInt((float)((region.endTime - region.startTime) * clipInfo.FramePerSecond)); double widthPerFrame = rect.width / numFrames; TimelineClipSISData timelineClipSISData = curAsset.GetBoundTimelineClipSISData(); if (null != timelineClipSISData) { timelineClipSISData.SetTimelineWidthPerFrame(widthPerFrame); } } }
public IEnumerator ReloadPlayableAsset() { PlayableDirector director = EditorUtilityTest.NewSceneWithDirector(); TimelineClip clip = EditorUtilityTest.CreateTestSISTimelineClip(director); StreamingImageSequencePlayableAsset sisAsset = clip.asset as StreamingImageSequencePlayableAsset; Assert.IsNotNull(sisAsset); string folder = sisAsset.GetFolder(); Assert.IsNotNull(folder); int numOriginalImages = sisAsset.GetNumImages(); Assert.Greater(numOriginalImages, 0); List <WatchedFileInfo> testImages = sisAsset.FindImages(folder); List <string> copiedImagePaths = new List <string>(testImages.Count); foreach (WatchedFileInfo imageFile in testImages) { string fileName = imageFile.GetName(); string src = Path.Combine(folder, fileName); string dest = Path.Combine(folder, "Copied_" + fileName); File.Copy(src, dest, true); copiedImagePaths.Add(dest); } yield return(null); sisAsset.Reload(); yield return(null); Assert.AreEqual(numOriginalImages * 2, sisAsset.GetNumImages()); //Cleanup foreach (string imagePath in copiedImagePaths) { File.Delete(imagePath); } EditorUtilityTest.DestroyTestTimelineAssets(clip); yield return(null); }
public IEnumerator ResetFrameMarkers() { PlayableDirector director = EditorUtilityTest.NewSceneWithDirector(); TimelineClip clip = EditorUtilityTest.CreateTestSISTimelineClip(director); StreamingImageSequencePlayableAsset sisAsset = clip.asset as StreamingImageSequencePlayableAsset; Assert.IsNotNull(sisAsset); yield return(null); SISClipData clipData = sisAsset.GetBoundClipData(); Assert.IsNotNull(clipData); clipData.RequestFrameMarkers(true); yield return(null); //Change image to false StreamingImageSequenceTrack track = clip.GetParentTrack() as StreamingImageSequenceTrack; Assert.IsNotNull(track); foreach (var m in track.GetMarkers()) { FrameMarker marker = m as FrameMarker; Assert.IsNotNull(marker); marker.SetFrameUsed(false); UnityEngine.Assertions.Assert.IsFalse(marker.IsFrameUsed()); } yield return(null); sisAsset.ResetPlayableFrames(); yield return(null); //Check if all markers have been reset to used foreach (var m in track.GetMarkers()) { FrameMarker marker = m as FrameMarker; Assert.IsNotNull(marker); UnityEngine.Assertions.Assert.IsTrue(marker.IsFrameUsed()); } yield return(null); EditorUtilityTest.DestroyTestTimelineAssets(clip); yield return(null); }
//---------------------------------------------------------------------------------------------------------------------- //Called when a clip is changed by the Editor. (TrimStart, TrimEnd, etc) public override void OnClipChanged(TimelineClip clip) { base.OnClipChanged(clip); StreamingImageSequencePlayableAsset sisAsset = clip.asset as StreamingImageSequencePlayableAsset; if (null == sisAsset) { Debug.LogError("[SIS] Clip Internal Error: Invalid Asset"); return; } EditorCurveBinding curveBinding = StreamingImageSequencePlayableAsset.GetTimeCurveBinding(); AnimationCurve curve = ExtendedClipEditorUtility.ValidateTimelineClipCurve(clip, curveBinding); //Always set the curve to clipData ExtendedClipEditorUtility.SetClipDataCurve <SISClipData>(sisAsset, curve); }
public IEnumerator SetPlayableAssetFPS() { PlayableDirector director = EditorUtilityTest.NewSceneWithDirector(); TimelineClip clip = EditorUtilityTest.CreateTestSISTimelineClip(director); StreamingImageSequencePlayableAsset sisAsset = clip.asset as StreamingImageSequencePlayableAsset; Assert.IsNotNull(sisAsset); //Make sure that we have some images int numImages = sisAsset.GetNumImages(); Assert.IsTrue(numImages > 0); yield return(null); //Set animationCurve with half speed SISClipData sisClipData = sisAsset.GetBoundClipData(); Assert.IsNotNull(sisClipData); float origCurveDuration = sisClipData.CalculateCurveDuration(); AnimationCurve halfSpeedCurve = AnimationCurve.Linear(0, 0, origCurveDuration * 2, 1.0f); AnimationUtility.SetEditorCurve(clip.curves, StreamingImageSequencePlayableAsset.GetTimeCurveBinding(), halfSpeedCurve); yield return(null); float origFPS = SISPlayableAssetUtility.CalculateFPS(sisAsset); float origDuration = (float)clip.duration; float origTimeScale = (float)clip.timeScale; SetFPSAndCheck(sisAsset, origFPS * 8.0f); SetFPSAndCheck(sisAsset, origFPS / 16.0f); SetFPSAndCheck(sisAsset, origFPS * 0.25f); SetFPSAndCheck(sisAsset, origFPS * 4.0f); SetFPSAndCheck(sisAsset, origFPS); yield return(null); //Check if we are back Assert.IsTrue(Mathf.Approximately(origFPS, SISPlayableAssetUtility.CalculateFPS(sisAsset))); Assert.IsTrue(Mathf.Approximately(origDuration, (float)clip.duration)); Assert.IsTrue(Mathf.Approximately(origTimeScale, (float)clip.timeScale)); EditorUtilityTest.DestroyTestTimelineAssets(clip); yield return(null); }
//---------------------------------------------------------------------------------------------------------------------- ///<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(); StreamingImageSequencePlayableAsset playableAsset = playableFrame.GetTimelineClipAsset <StreamingImageSequencePlayableAsset>(); if (null == playableAsset) { return(ActionValidity.NotApplicable); } } return(ActionValidity.Valid); }
//---------------------------------------------------------------------------------------------------------------------- /// Import images in the path to create StreamingImageSequence assets with those images /// <param name="path"> Can be a directory path or a file path</param> /// <param name="targetAsset"> The target asset where the images are assigned to</param> /// <param name="askToCopy"> Ask to copy if path is not under StreamingAssets. Default to true</param> internal static void ImportImages(string path, StreamingImageSequencePlayableAsset targetAsset, bool askToCopy = true) { Assert.IsFalse(string.IsNullOrEmpty(path)); FindFolderAndImages(path, out string folder, out List <string> relFilePaths); if (relFilePaths.Count <= 0) { EditorUtility.DisplayDialog(StreamingImageSequenceConstants.DIALOG_HEADER, @"No files in folder:: " + folder, "OK"); return; } //Estimate the asset name. Use the filename without numbers at the end string assetName = EstimateAssetName(relFilePaths[0]); // set dest folder string streamingAssetsPath = AssetEditorUtility.NormalizeAssetPath(Application.streamingAssetsPath); //Set importer param ImageFileImporterParam importerParam = new ImageFileImporterParam { strSrcFolder = folder, RelativeFilePaths = relFilePaths, CopyToStreamingAssets = true, TargetAsset = targetAsset }; //Import immediately if the assets are already under StreamingAssets if (folder.StartsWith(streamingAssetsPath) || !askToCopy) { importerParam.strDstFolder = importerParam.strSrcFolder; importerParam.CopyToStreamingAssets = false; ImageSequenceImporter.Import(importerParam); } else { importerParam.strDstFolder = Path.Combine(streamingAssetsPath, assetName).Replace("\\", "/"); ImageSequenceImportWindow.Show(importerParam); } }
///<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(); StreamingImageSequencePlayableAsset playableAsset = playableFrame.GetTimelineClipAsset <StreamingImageSequencePlayableAsset>(); if (null == playableAsset) { return(false); } FrameMarkerInspector.EditPlayableFrame(playableFrame, playableAsset); } return(true); }
internal static void EditPlayableFrame(SISPlayableFrame playableFrame, StreamingImageSequencePlayableAsset sisPlayableAsset) { //Find the correct imageIndex. The number of frames in the clip may be more/less than the number of images int playableFrameIndex = playableFrame.GetIndex(); int numPlayableFrames = sisPlayableAsset.GetBoundClipData().GetNumPlayableFrames(); int numImages = sisPlayableAsset.GetNumImages(); int index = Mathf.FloorToInt(playableFrameIndex * ((float)numImages / numPlayableFrames)); string filePath = sisPlayableAsset.GetImageFilePath(index); if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath)) { EditorUtility.DisplayDialog(StreamingImageSequenceConstants.DIALOG_HEADER, "Image does not exist: " + filePath, "Ok"); return; } LaunchImageApplicationExternalTool(Path.GetFullPath(filePath)); }
void SetFPSAndCheck(StreamingImageSequencePlayableAsset sisAsset, float newFPS) { SISClipData sisClipData = sisAsset.GetBoundClipData(); Assert.IsNotNull(sisClipData); TimelineClip clip = sisClipData.GetOwner(); Assert.IsNotNull(clip); float prevFPS = SISPlayableAssetUtility.CalculateFPS(sisAsset); float prevClipDuration = (float)clip.duration; float prevTimeScale = (float)clip.timeScale; Assert.Greater(prevFPS, 0); float fpsMultiplier = newFPS / prevFPS; Assert.Greater(fpsMultiplier, 0); float timeMultiplier = 1.0f / fpsMultiplier; SISPlayableAssetUtility.SetFPS(sisAsset, newFPS); Assert.IsTrue(Mathf.Approximately(prevClipDuration * timeMultiplier, (float)clip.duration)); Assert.IsTrue(Mathf.Approximately(prevTimeScale * fpsMultiplier, (float)clip.timeScale)); }
public IEnumerator ImportFromStreamingAssets() { PlayableDirector director = EditorUtilityTest.NewSceneWithDirector(); TimelineClip clip = EditorUtilityTest.CreateTestSISTimelineClip(director); StreamingImageSequencePlayableAsset sisAsset = clip.asset as StreamingImageSequencePlayableAsset; Assert.IsNotNull(sisAsset); //Copy test data to streamingAssetsPath const string DEST_FOLDER_NAME = "ImportFromStreamingAssetsTest"; string streamingAssetsFolder = AssetUtility.NormalizeAssetPath(Application.streamingAssetsPath); string destFolderGUID = AssetDatabase.CreateFolder(streamingAssetsFolder, DEST_FOLDER_NAME); string destFolder = AssetDatabase.GUIDToAssetPath(destFolderGUID); int numImages = sisAsset.GetNumImages(); for (int i = 0; i < numImages; ++i) { string src = sisAsset.GetImageFilePath(i); Assert.IsNotNull(src); string dest = Path.Combine(destFolder, Path.GetFileName(src)); File.Copy(src, dest, true); } AssetDatabase.Refresh(); yield return(null); ImageSequenceImporter.ImportImages(destFolder, sisAsset); yield return(null); Assert.AreEqual(destFolder, sisAsset.GetFolder()); //Cleanup AssetDatabase.DeleteAsset(destFolder); EditorUtilityTest.DestroyTestTimelineAssets(clip); yield return(null); }
//---------------------------------------------------------------------------------------------------------------------- /// <summary> /// StreamingImageSequencePlayableAsset GUI Drawing /// </summary> public override void OnInspectorGUI() { if (null == m_asset) return; using (new EditorGUILayout.VerticalScope (GUI.skin.box)) { m_resolutionFoldout = EditorGUILayout.Foldout(m_resolutionFoldout, "Resolution"); if (m_resolutionFoldout) { ImageDimensionInt res = m_asset.GetResolution(); EditorGUILayout.LabelField("Width", $"{res.Width } px"); EditorGUILayout.LabelField("Height", $"{res.Height } px"); } GUILayout.Space(4f); } GUILayout.Space(4f); using (new EditorGUILayout.VerticalScope(GUI.skin.box)) { GUILayout.Label("Folder", "BoldLabel"); GUILayout.Space(4f); DrawFolderGUI(); } GUILayout.Space(4f); using (new EditorGUILayout.VerticalScope(GUI.skin.box)) { int numImages = m_asset.GetNumImages(); EditorGUILayout.BeginHorizontal(); GUILayout.Label("Images: " + numImages, "BoldLabel"); if (GUILayout.Button("Reload", GUILayout.Width(50))) { m_asset.Reload(); } EditorGUILayout.EndHorizontal(); using (new EditorGUI.DisabledScope(0 == numImages)) { if (0 == numImages) EditorGUILayout.IntField("FPS", 0); else { TimelineClip clip = m_asset.GetBoundClipData()?.GetOwner(); //There is no assigned clip if the playableAsset is not loaded in TimelineWindow if (null != clip) { EditorGUIDrawerUtility.DrawUndoableGUI(clip.GetParentTrack(), "Change FPS", /*guiFunc=*/ ()=> { float fps = SISPlayableAssetUtility.CalculateFPS(m_asset); float val = EditorGUILayout.FloatField("FPS", fps); return Mathf.Max(0.1f, val); }, /*updateFunc=*/ (float newFPS) => { SISPlayableAssetUtility.SetFPS(m_asset, newFPS); } ); } } } GUILayout.Space(4f); m_imageListFoldout = EditorGUILayout.Foldout(m_imageListFoldout, "Images"); if (m_imageListFoldout) { DoImageGUI(); } } if (null == TimelineEditor.selectedClip) return; GUILayout.Space(15); //Frame markers if (TimelineEditor.selectedClip.asset == m_asset) { using (new EditorGUILayout.HorizontalScope()) { InspectorUtility.DrawFrameMarkersGUI(m_asset); if (GUILayout.Button("Reset", GUILayout.Width(50f))) { m_asset.ResetPlayableFrames(); } } } GUILayout.Space(15); using (new EditorGUILayout.VerticalScope(GUI.skin.box)) { EditorGUILayout.LabelField("Background Colors"); ++EditorGUI.indentLevel; EditorGUIDrawerUtility.DrawUndoableGUI(m_asset, "Change BG Color", /*guiFunc=*/ ()=> EditorGUILayout.ColorField("In Timeline Window", m_asset.GetTimelineBGColor()), /*updateFunc=*/ (Color newColor) => { m_asset.SetTimelineBGColor(newColor); } ); --EditorGUI.indentLevel; GUILayout.Space(15); } if (GUILayout.Button("Reset Curve (Not Undoable)")) { //AnimationUtility.SetEditorCurve(), which is called below, doesn't seem to be undoable EditorCurveBinding curveBinding = StreamingImageSequencePlayableAsset.GetTimeCurveBinding(); ExtendedClipEditorUtility.ResetClipDataCurve(m_asset, curveBinding); } }
/// <param name="importerMode"> Importer mode: StreamingAssets or SpriteAnimation</param> /// <param name="path"> Can be a directory path or a file path</param> public static void ImportPictureFiles(PictureFileImporterParam.Mode importerMode, string path, StreamingImageSequencePlayableAsset targetAsset) { Assert.IsFalse(string.IsNullOrEmpty(path)); //Convert path to folder here string folder = path; FileAttributes attr = File.GetAttributes(path); if (!attr.HasFlag(FileAttributes.Directory)) { folder = Path.GetDirectoryName(folder); } string fullSrcPath = Path.GetFullPath(folder).Replace("\\", "/"); Uri fullSrcPathUri = new Uri(fullSrcPath + "/"); if (string.IsNullOrEmpty(folder)) { Debug.LogError(@"Folder is empty. Path: " + path); return; } //Enumerate all files with the supported extensions and sort List <string> relFilePaths = new List <string>(); string[] extensions = { "*." + PictureFileImporter.PNG_EXTENSION, "*." + PictureFileImporter.TGA_EXTENSION, }; foreach (string ext in extensions) { IEnumerable <string> files = Directory.EnumerateFiles(fullSrcPath, ext, SearchOption.AllDirectories); foreach (string filePath in files) { Uri curPathUri = new Uri(filePath.Replace("\\", "/")); Uri diff = fullSrcPathUri.MakeRelativeUri(curPathUri); relFilePaths.Add(diff.OriginalString); } } if (relFilePaths.Count <= 0) { EditorUtility.DisplayDialog(StreamingImageSequenceConstants.DIALOG_HEADER, @"No files in folder:: " + folder, "OK"); return; } relFilePaths.Sort(FileNameComparer); //Estimate the asset name. Use the filename without numbers at the end string assetName = EstimateAssetName(relFilePaths[0]); // set dest folder string rootDestFolder = Application.streamingAssetsPath; if (importerMode == PictureFileImporterParam.Mode.SpriteAnimation) { rootDestFolder = Application.dataPath; } //Set importer param PictureFileImporterParam importerParam = new PictureFileImporterParam { strAssetName = assetName, strSrcFolder = folder, RelativeFilePaths = relFilePaths, mode = importerMode, DoNotCopy = false, TargetAsset = targetAsset }; if (fullSrcPath.StartsWith(rootDestFolder)) { //Import immediately if the assets are already under Unity importerParam.strDstFolder = importerParam.strSrcFolder; importerParam.DoNotCopy = true; PictureFileImporter.Import(importerParam); } else { importerParam.strDstFolder = Path.Combine(rootDestFolder, assetName).Replace("\\", "/"); PictureFileImportWindow.SetParam(importerParam); PictureFileImportWindow.InitWindow(); } }