//---------------------------------------------------------------------------------------------------------------------- private void CreateAndDeleteSceneCachePlayerPrefab(string sceneCachePath) { Assert.IsTrue(File.Exists(sceneCachePath)); const string DEST_PREFAB_PATH = "Assets/TestSceneCache.prefab"; const string ASSETS_FOLDER = "Assets/TestSceneCacheAssets"; bool prefabCreated = SceneCachePlayerEditorUtility.CreateSceneCachePlayerAndPrefab( Path.GetFullPath(sceneCachePath), DEST_PREFAB_PATH, ASSETS_FOLDER, out SceneCachePlayer player, out GameObject prefab ); Assert.IsTrue(prefabCreated); string savedScFilePath = player.GetSceneCacheFilePath(); Assert.IsTrue(AssetEditorUtility.IsPathNormalized(savedScFilePath), $"{savedScFilePath} is not normalized"); //Check player Assert.IsNotNull(player); Assert.IsTrue(player.IsSceneCacheOpened()); Assert.IsTrue(player.gameObject.IsPrefabInstance()); //Check the prefab Assert.IsNotNull(prefab); string prefabPath = AssetDatabase.GetAssetPath(prefab); Assert.IsFalse(string.IsNullOrEmpty(prefabPath)); Assert.AreEqual(DEST_PREFAB_PATH, prefabPath); DeleteSceneCachePlayerPrefab(prefab); }
public IEnumerator CreateAndFindAsset() { const string TEST_ASSETS_ROOT = "Assets/TestRunner"; const string MAT_FOLDER = TEST_ASSETS_ROOT + "/Materials"; const string MAT_NAME = "TestRunnerMaterial"; Directory.CreateDirectory(MAT_FOLDER); string path = AssetDatabase.GenerateUniqueAssetPath($"{MAT_FOLDER}/{MAT_NAME}.mat"); AssetDatabase.CreateAsset(new Material(Shader.Find("Standard")), path); yield return(YieldEditorUtility.WaitForFramesAndIncrementUndo(1)); HashSet <string> paths = AssetEditorUtility.FindAssetPaths("t:material", MAT_NAME); Assert.AreEqual(1, paths.Count); //exact name paths = AssetEditorUtility.FindAssetPaths("t:material", MAT_NAME.Substring(0, MAT_NAME.Length - 3)); Assert.AreEqual(0, paths.Count); paths = AssetEditorUtility.FindAssetPaths("t:material", MAT_NAME, new[] { "Assets" }, shouldSearchSubFolder: true); Assert.AreEqual(1, paths.Count); //exact folder paths = AssetEditorUtility.FindAssetPaths("t:material", MAT_NAME, new[] { "Assets" }, shouldSearchSubFolder: false); Assert.AreEqual(0, paths.Count); yield return(YieldEditorUtility.WaitForFramesAndIncrementUndo(1)); AssetDatabase.DeleteAsset(path); AssetDatabase.DeleteAsset(TEST_ASSETS_ROOT); }
//---------------------------------------------------------------------------------------------------------------------- void OnOutputPathSelectButtonClicked() { string path = EditorUtility.OpenFolderPanel("Select Scene Cache Output Path", m_generatedSCResPathTextField.value, ""); if (string.IsNullOrEmpty(path)) { return; } if (!path.StartsWith(Application.dataPath)) { EditorUtility.DisplayDialog("MeshSync", $"Invalid path: {path}. " + "Path has to be under the Assets folder.", "Ok"); return; } MeshSyncProjectSettings settings = MeshSyncProjectSettings.GetOrCreateSettings(); path = AssetEditorUtility.NormalizePath(path); settings.SetSceneCacheOutputPath(path); settings.Save(); RefreshSettings(); }
public void CopySceneCacheToStreamingAssets() { //Initial setup const string DEST_PREFAB_PATH = "Assets/TestSceneCache.prefab"; const string ASSETS_FOLDER = "Assets/TestSceneCacheAssets"; string destFolder = Path.Combine(Application.streamingAssetsPath, "TestRunner"); string streamingAssetsPath = Path.Combine(destFolder, "Copied.sc"); bool prefabCreated = SceneCachePlayerEditorUtility.CreateSceneCachePlayerAndPrefab( Path.GetFullPath(MeshSyncTestEditorConstants.CUBE_TEST_DATA_PATH), DEST_PREFAB_PATH, ASSETS_FOLDER, out SceneCachePlayer player, out GameObject prefab ); Assert.IsTrue(prefabCreated); //Copy Directory.CreateDirectory(destFolder); File.Copy(player.GetSceneCacheFilePath(), streamingAssetsPath); Assert.IsTrue(File.Exists(streamingAssetsPath)); AssetDatabase.Refresh(); //Change ChangeSceneCacheFileAndVerify(player, streamingAssetsPath); Assert.IsTrue(player.IsSceneCacheOpened()); //Cleanup Object.DestroyImmediate(player.gameObject); DeleteSceneCachePlayerPrefab(prefab); AssetDatabase.DeleteAsset(AssetEditorUtility.NormalizePath(streamingAssetsPath)); AssetDatabase.DeleteAsset(AssetEditorUtility.NormalizePath(destFolder)); AssetDatabase.Refresh(); }
internal bool OpenCacheInEditor(string path) { string normalizedPath = System.IO.Path.GetFullPath(path).Replace('\\', '/'); normalizedPath = AssetEditorUtility.NormalizePath(normalizedPath); if (!OpenCacheInternal(normalizedPath, updateNonMaterialAssets: true)) { return(false); } ExportMaterials(false, true); ResetTimeAnimationInEditor(); if (m_sceneCache) { SceneData scene = LoadSceneData(m_loadedTime, out _); //[TODO-sin: 2022-3-9] Review if this code is necessary. //Was added in commit b60337aff38e55febf81a9b7c741458eff34a919 on August 18, 2019. if (scene && !scene.submeshesHaveUniqueMaterial) { m_config.SyncMaterialList = false; } } return(true); }
//---------------------------------------------------------------------------------------------------------------------- public void DrawServerSettings(MeshSyncServer t) { var styleFold = EditorStyles.foldout; styleFold.fontStyle = FontStyle.Bold; bool isServerStarted = m_meshSyncServer.IsServerStarted(); string serverStatus = isServerStarted ? "Server (Status: Started)" : "Server (Status: Stopped)"; t.foldServerSettings = EditorGUILayout.Foldout(t.foldServerSettings, serverStatus, true, styleFold); if (t.foldServerSettings) { bool autoStart = EditorGUILayout.Toggle("Auto Start", m_meshSyncServer.IsAutoStart()); m_meshSyncServer.SetAutoStartServer(autoStart); //Draw GUI that are disabled when autoStart is true EditorGUI.BeginDisabledGroup(autoStart); int serverPort = EditorGUILayout.IntField("Server Port:", (int)m_meshSyncServer.GetServerPort()); m_meshSyncServer.SetServerPort((ushort)serverPort); GUILayout.BeginHorizontal(); if (isServerStarted) { if (GUILayout.Button("Stop", GUILayout.Width(110.0f))) { m_meshSyncServer.StopServer(); } } else { if (GUILayout.Button("Start", GUILayout.Width(110.0f))) { m_meshSyncServer.StartServer(); } } GUILayout.EndHorizontal(); EditorGUI.EndDisabledGroup(); string prevFolder = t.GetAssetsFolder(); string selectedFolder = AssetEditorUtility.NormalizePath( EditorGUIDrawerUtility.DrawFolderSelectorGUI("Asset Dir", "Asset Dir", prevFolder, null) ); if (selectedFolder != prevFolder) { if (string.IsNullOrEmpty(selectedFolder) || !AssetEditorUtility.IsPathNormalized(selectedFolder)) { Debug.LogError($"[MeshSync] {selectedFolder} is not under Assets. Ignoring."); } else { t.SetAssetsFolder(selectedFolder); } } Transform rootObject = (Transform)EditorGUILayout.ObjectField("Root Object", t.GetRootObject(), typeof(Transform), allowSceneObjects: true); t.SetRootObject(rootObject); EditorGUILayout.Space(); } }
//---------------------------------------------------------------------------------------------------------------------- private IEnumerator CopyAndDeleteSampleAsset(string destFolder) { // Assert.IsTrue(File.Exists(SRC_IMAGE_PATH)); string uniqueName = Path.GetFileName(FileUtil.GetUniqueTempPathInProject()); Assert.IsFalse(string.IsNullOrEmpty(uniqueName)); Directory.CreateDirectory(destFolder); int numDuplicates = 10; int numDigits = MathUtility.GetNumDigits(numDuplicates); for (int i = 0; i < numDuplicates; ++i) { string destFileName = i.ToString($"D{numDigits}") + ".png"; string destPath = Path.Combine(destFolder, destFileName); File.Copy(SRC_IMAGE_PATH, destPath); Assert.IsTrue(File.Exists(destPath)); } yield return(null); AssetEditorUtility.DeleteAssetsOrFiles(destFolder, "*.png"); yield return(null); string[] files = Directory.GetFiles(destFolder); Assert.IsTrue(0 == files.Length); Directory.Delete(destFolder); }
public void CreateAndDeleteTextInTempCachePath() { const string TEST_FILE_NAME = "AssetEditorUtilityTest.txt"; const string TEXT = "This is a test from AnimeToolbox"; string path = Path.Combine(Application.temporaryCachePath, TEST_FILE_NAME); File.WriteAllText(path, TEXT); Assert.IsTrue(File.Exists(path)); AssetEditorUtility.DeleteAssetsOrFiles(Application.temporaryCachePath, TEST_FILE_NAME); Assert.IsFalse(File.Exists(path)); }
public void CreateAndDeleteScriptableObjectInDataPath() { const string TEST_FILE_NAME = "AssetEditorUtilityTest.asset"; IntScriptableObject asset = ScriptableObject.CreateInstance <IntScriptableObject>(); string path = AssetEditorUtility.NormalizePath(Path.Combine(Application.dataPath, TEST_FILE_NAME)); AssetEditorUtility.OverwriteAsset(asset, path); Assert.IsTrue(File.Exists(path)); AssetEditorUtility.DeleteAssetsOrFiles(Application.dataPath, TEST_FILE_NAME); Assert.IsFalse(File.Exists(path)); }
//---------------------------------------------------------------------------------------------------------------------- bool DrawCacheFile(SceneCachePlayer t) { t.ShowCacheFileInInspector(EditorGUILayout.Foldout(t.IsCacheFileShownInInspector(), "File", true, GetDefaultFoldoutStyle())); if (!t.IsCacheFileShownInInspector()) { return(false); } bool changed = false; //Show Selector GUI. Check if we should reopen string fullPath = t.GetSceneCacheFilePath(); string prevNormalizedPath = AssetEditorUtility.NormalizePath(fullPath); string newNormalizedPath = EditorGUIDrawerUtility.DrawFileSelectorGUI("Cache File Path", "MeshSync", prevNormalizedPath, "sc", OnSceneCacheFileReload); newNormalizedPath = AssetEditorUtility.NormalizePath(newNormalizedPath); if (newNormalizedPath != prevNormalizedPath) { ChangeSceneCacheFileInInspector(t, newNormalizedPath); } if (!string.IsNullOrEmpty(fullPath) && !fullPath.StartsWith(Application.streamingAssetsPath)) { GUILayout.BeginHorizontal(); const float BUTTON_WIDTH = 50.0f; if (GUILayout.Button("Copy", GUILayout.Width(BUTTON_WIDTH))) { string dstPath = Misc.CopyFileToStreamingAssets(fullPath); ChangeSceneCacheFileInInspector(t, dstPath); } GUILayout.Label("Scene Cache file to StreamingAssets"); EditorGUILayout.LabelField("(RECOMMENDED)", EditorStyles.boldLabel); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.Space(15); } EditorGUILayout.Space(); //[TODO-sin: 2022-3-14] This may cause crash when sliding the values back and forth. Find out why // preload { // changed |= EditorGUIDrawerUtility.DrawUndoableGUI(t, "SceneCache: Preload", // guiFunc: () => (EditorGUILayout.IntSlider("Preload Length", t.GetPreloadLength(), 0, t.frameCount)), // updateFunc: (int preloadLength) => { t.SetPreloadLength(preloadLength); }); } return(changed); }
protected override void OnAfterDeserializeMeshSyncPlayerV() { if (m_sceneCachePlayerVersion == CUR_SCENE_CACHE_PLAYER_VERSION) { return; } #if UNITY_EDITOR if (m_sceneCachePlayerVersion < (int)SceneCachePlayerVersion.NORMALIZED_PATH_0_9_2) { m_sceneCacheFilePath = AssetEditorUtility.NormalizePath(m_sceneCacheFilePath); } #endif m_sceneCachePlayerVersion = CUR_SCENE_CACHE_PLAYER_VERSION; }
//---------------------------------------------------------------------------------------------------------------------- static bool CopyDirectory(string src, string dst, bool overwrite = false) { DirectoryInfo dir = new DirectoryInfo(src); if (!dir.Exists) { return(false); } Directory.CreateDirectory(dst); Regex isMeta = new Regex(@"\.meta$"); foreach (FileInfo file in dir.GetFiles()) { if (isMeta.Match(file.Name).Success) { continue; // ignore .meta } string destPath = Path.Combine(dst, file.Name); //Skip existing files if overwrite is false if (!overwrite && File.Exists(destPath)) { continue; } file.CopyTo(destPath, overwrite); // ImportAsset() require relative path from Assets/ string importPath = AssetEditorUtility.NormalizePath(destPath); AssetDatabase.ImportAsset(importPath); } // recurse foreach (DirectoryInfo subDir in dir.GetDirectories()) { CopyDirectory(subDir.FullName, Path.Combine(dst, subDir.Name), overwrite); } return(true); }
//---------------------------------------------------------------------------------------------------------------------- static TestDataComponents ChangeSceneCacheFileAndVerify(SceneCachePlayer player, string scPath) { SceneCachePlayerEditorUtility.ChangeSceneCacheFile(player, scPath); string savedScFilePath = player.GetSceneCacheFilePath(); Assert.AreEqual(AssetEditorUtility.NormalizePath(scPath), savedScFilePath); Assert.IsTrue(AssetEditorUtility.IsPathNormalized(savedScFilePath), $"{savedScFilePath} is not normalized"); Assert.IsTrue(player.transform.childCount > 0); TestDataComponents ret = new TestDataComponents( player.GetComponentInChildren <Camera>(), player.GetComponentInChildren <Light>(), player.GetComponentInChildren <MeshRenderer>() ); Assert.IsNotNull(ret.cam); Assert.IsNotNull(ret.light); Assert.IsNotNull(ret.meshRenderer); return(ret); }
public IEnumerator CreateAndLoadAsset() { string materialName = "TestRunnerMaterial"; Material createdMat = new Material(Shader.Find("Standard")) { name = materialName }; string path = AssetEditorUtility.CreateSceneAsset(createdMat, "mat"); yield return(YieldEditorUtility.WaitForFramesAndIncrementUndo(1)); string[] guids = AssetDatabase.FindAssets($"t:material {materialName}"); Assert.IsNotNull(guids); Assert.Greater(guids.Length, 0); Material mat = AssetEditorUtility.LoadAssetByGUID <Material>(guids[0]); Assert.IsNotNull(mat); yield return(YieldEditorUtility.WaitForFramesAndIncrementUndo(1)); AssetDatabase.DeleteAsset(path); }
public IEnumerator ImportFromStreamingAssets() { PlayableDirector director = EditorUtilityTest.NewSceneWithDirector(); TimelineClip clip = EditorUtilityTest.CreateTestTimelineClip(director); StreamingImageSequencePlayableAsset sisAsset = clip.asset as StreamingImageSequencePlayableAsset; Assert.IsNotNull(sisAsset); //Copy test data to streamingAssetsPath const string DEST_FOLDER_NAME = "ImportFromStreamingAssetsTest"; string streamingAssetsFolder = AssetEditorUtility.NormalizeAssetPath(Application.streamingAssetsPath); string destFolderGUID = AssetDatabase.CreateFolder(streamingAssetsFolder, DEST_FOLDER_NAME); string destFolder = AssetDatabase.GUIDToAssetPath(destFolderGUID); string srcFolder = sisAsset.GetFolder(); IList <string> imageFileNames = sisAsset.GetImageFileNames(); foreach (string imageFileName in imageFileNames) { string src = Path.Combine(srcFolder, imageFileName); string dest = Path.Combine(destFolder, imageFileName); 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); }
private protected override void OnAfterDeserializeMeshSyncPlayerV() { if (m_sceneCachePlayerVersion == CUR_SCENE_CACHE_PLAYER_VERSION) { return; } #if UNITY_EDITOR if (m_sceneCachePlayerVersion < (int)SceneCachePlayerVersion.NORMALIZED_PATH_0_9_2) { m_sceneCacheFilePath = AssetEditorUtility.NormalizePath(m_sceneCacheFilePath); } #pragma warning disable 612 if (m_sceneCachePlayerVersion < (int)SceneCachePlayerVersion.PLAYBACK_MODE_0_12_0 && m_timeUnit == TimeUnit.Frames) { m_timeUnit = TimeUnit.Seconds; m_resetTimeAnimationOnEnable = true; } #pragma warning restore 612 #endif m_sceneCachePlayerVersion = CUR_SCENE_CACHE_PLAYER_VERSION; }
internal bool OpenCacheInEditor(string path) { string normalizedPath = System.IO.Path.GetFullPath(path).Replace('\\', '/'); normalizedPath = AssetEditorUtility.NormalizePath(normalizedPath); if (!OpenCacheInternal(normalizedPath)) { return(false); } UpdatePlayer(/* updateNonMaterialAssets = */ true); ExportMaterials(false, true); ResetTimeAnimation(); SceneData scene = GetLastScene(); if (!scene.submeshesHaveUniqueMaterial) { m_config.SyncMaterialList = false; } return(true); }
//---------------------------------------------------------------------------------------------------------------------- void VerifyNormalizedPath(string input, string expected) { string normalizedPath = AssetEditorUtility.NormalizePath(input); Assert.AreEqual(expected, normalizedPath); }
void VerifyPathIsAssetPath(string path, bool expectedResult) { bool isAssetPath = AssetEditorUtility.IsPathNormalized(path); Assert.AreEqual(expectedResult, isAssetPath); }
//---------------------------------------------------------------------------------------------------------------------- bool DrawCacheSettings(SceneCachePlayer t) { bool changed = false; GUIStyle styleFold = EditorStyles.foldout; styleFold.fontStyle = FontStyle.Bold; t.foldCacheSettings = EditorGUILayout.Foldout(t.foldCacheSettings, "Player", true, styleFold); if (t.foldCacheSettings) { //Show Selector GUI. Check if we should reopen string fullPath = t.GetSceneCacheFilePath(); string prevNormalizedPath = AssetEditorUtility.NormalizePath(fullPath); string newNormalizedPath = EditorGUIDrawerUtility.DrawFileSelectorGUI("Cache File Path", "MeshSync", prevNormalizedPath, "sc", OnSceneCacheFileReload); newNormalizedPath = AssetEditorUtility.NormalizePath(newNormalizedPath); if (newNormalizedPath != prevNormalizedPath) { ChangeSceneCacheFileInInspector(t, newNormalizedPath); } if (!string.IsNullOrEmpty(fullPath) && !fullPath.StartsWith(Application.streamingAssetsPath)) { GUILayout.BeginHorizontal(); const float BUTTON_WIDTH = 50.0f; if (GUILayout.Button("Copy", GUILayout.Width(BUTTON_WIDTH))) { string dstPath = Misc.CopyFileToStreamingAssets(fullPath); ChangeSceneCacheFileInInspector(t, dstPath); } GUILayout.Label("Scene Cache file to StreamingAssets"); EditorGUILayout.LabelField("(RECOMMENDED)", EditorStyles.boldLabel); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.Space(15); } EditorGUILayout.Space(); //Time Unit changed |= EditorGUIDrawerUtility.DrawUndoableGUI(t, "SceneCache: Time Unit", guiFunc: () => (SceneCachePlayer.TimeUnit)EditorGUILayout.Popup("Time Unit", (int)t.GetTimeUnit(), TIME_UNIT_ENUMS), updateFunc: (SceneCachePlayer.TimeUnit timeUnit) => { t.SetTimeUnit(timeUnit); t.ResetTimeAnimation(); } ); SceneCachePlayer.TimeUnit selectedTimeUnit = t.GetTimeUnit(); if (selectedTimeUnit == SceneCachePlayer.TimeUnit.Seconds) { changed |= EditorGUIDrawerUtility.DrawUndoableGUI(t, "SceneCache: Time", guiFunc: () => (EditorGUILayout.FloatField("Time", t.GetTime())), updateFunc: (float time) => { t.SetTime(time); }); changed |= EditorGUIDrawerUtility.DrawUndoableGUI(t, "SceneCache: Interpolation", guiFunc: () => (EditorGUILayout.Toggle("Interpolation", t.GetInterpolation())), updateFunc: (bool toggle) => { t.SetInterpolation(toggle); }); } else if (selectedTimeUnit == SceneCachePlayer.TimeUnit.Frames) { changed |= EditorGUIDrawerUtility.DrawUndoableGUI(t, "SceneCache: Base Frame", guiFunc: () => ((SceneCachePlayer.BaseFrame)EditorGUILayout.Popup("Base Frame", (int)t.GetBaseFrame(), BASE_FRAME_ENUMS)), updateFunc: (SceneCachePlayer.BaseFrame baseFrame) => { t.SetBaseFrame(baseFrame); t.ResetTimeAnimation(); }); changed |= EditorGUIDrawerUtility.DrawUndoableGUI(t, "SceneCache: Frame", guiFunc: () => (EditorGUILayout.IntField("Frame", t.GetFrame())), updateFunc: (int frame) => { t.SetFrame(frame); }); } // preload { changed |= EditorGUIDrawerUtility.DrawUndoableGUI(t, "SceneCache: Preload", guiFunc: () => (EditorGUILayout.IntSlider("Preload Length", t.GetPreloadLength(), 0, t.frameCount)), updateFunc: (int preloadLength) => { t.SetPreloadLength(preloadLength); }); } EditorGUILayout.Space(); } return(changed); }
//--------------------------------------------------------------------------------------------------------------------- /// <summary> /// Import a timeline file exported from DCC tools into the scene in the Timeline object /// </summary> /// <param name="jsTimelinePath">The path of the file</param> /// <param name="destFolder">The dest folder of the imported files</param> public static void ImportTimeline(string jsTimelinePath, string destFolder = "") { // prepare asset name, paths, etc string assetName = Path.GetFileNameWithoutExtension(jsTimelinePath); string timelineFolder = Path.GetDirectoryName(jsTimelinePath); if (string.IsNullOrEmpty(timelineFolder)) { Debug.LogError("Can't get directory name for: " + jsTimelinePath); return; } timelineFolder = Path.Combine(timelineFolder, destFolder, assetName).Replace("\\", "/"); //Check if we are exporting from external asset if (!timelineFolder.StartsWith("Assets/")) { timelineFolder = Path.Combine("Assets", destFolder, assetName); } Directory.CreateDirectory(timelineFolder); string strJson = File.ReadAllText(jsTimelinePath); TimelineParam container = JsonUtility.FromJson <TimelineParam>(strJson); string assetFolder = container.assetFolder; if (string.IsNullOrEmpty(assetFolder)) { assetFolder = Path.GetDirectoryName(jsTimelinePath); } //delete existing objects in the scene that is pointing to the Director string timelinePath = Path.Combine(timelineFolder, assetName + "_Timeline.playable").Replace("\\", "/"); PlayableDirector director = RemovePlayableFromDirectorsInScene(timelinePath); if (null == director) { GameObject directorGo = new GameObject(assetName); director = directorGo.AddComponent <PlayableDirector>(); } //Create timeline asset TimelineAsset asset = ScriptableObject.CreateInstance <TimelineAsset>(); AssetEditorUtility.OverwriteAsset(asset, timelinePath); director.playableAsset = asset; string strHome = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal); int numTracks = container.Tracks.Length; for (int index = numTracks - 1; index >= 0; index--) { var track = container.Tracks[index]; string strFootagePath = track.Footage; // remove '~' if necessary if (strFootagePath.StartsWith("~")) { strFootagePath = strHome + strFootagePath.Substring(1); } if (!Path.IsPathRooted(strFootagePath)) { strFootagePath = Path.Combine(assetFolder, strFootagePath); } string strFootageName = Path.GetFileNameWithoutExtension(strFootagePath); string strJsonFootage = File.ReadAllText(strFootagePath); AEFootageInfo footageInfo = JsonUtility.FromJson <AEFootageInfo>(strJsonFootage); int numImages = footageInfo.Pictures.Count; if (numImages > 0) { List <string> originalImagePaths = new List <string>(footageInfo.Pictures); for (int xx = 0; xx < numImages; ++xx) { string fileName = footageInfo.Pictures[xx]; // replace '~' with the path to home (for Linux environment if (fileName.StartsWith("~")) { fileName = strHome + fileName.Substring(1); } footageInfo.Pictures[xx] = Path.GetFileName(fileName); } string destFootageFolder = Application.streamingAssetsPath; destFootageFolder = Path.Combine(destFootageFolder, strFootageName).Replace("\\", "/"); Directory.CreateDirectory(destFootageFolder); //make sure the directory exists footageInfo.Folder = AssetUtility.NormalizeAssetPath(destFootageFolder); for (int i = 0; i < numImages; ++i) { string destFilePath = Path.Combine(destFootageFolder, footageInfo.Pictures[i]); if (File.Exists(destFilePath)) { File.Delete(destFilePath); } string srcFilePath = Path.GetFullPath(Path.Combine(assetFolder, originalImagePaths[i])).Replace("\\", "/"); FileUtil.CopyFileOrDirectory(srcFilePath, destFilePath); } } //Convert to WatchedFileInfo List <WatchedFileInfo> imageFiles = WatchedFileInfo.CreateList(footageInfo.Folder, footageInfo.Pictures); StreamingImageSequencePlayableAsset sisAsset = ScriptableObject.CreateInstance <StreamingImageSequencePlayableAsset>(); sisAsset.InitFolder(footageInfo.Folder, imageFiles, footageInfo.Resolution); string playableAssetPath = Path.Combine(timelineFolder, strFootageName + "_StreamingImageSequence.playable"); AssetEditorUtility.OverwriteAsset(sisAsset, playableAssetPath); StreamingImageSequenceTrack movieTrack = asset.CreateTrack <StreamingImageSequenceTrack>(null, strFootageName); TimelineClip clip = movieTrack.CreateDefaultClip(); clip.asset = sisAsset; clip.start = track.Start; clip.duration = track.Duration; clip.CreateCurves("Curves: " + clip.displayName); TimelineClipSISData sisData = new TimelineClipSISData(clip); sisAsset.InitTimelineClipCurve(clip); sisAsset.BindTimelineClipSISData(sisData); if (Object.FindObjectOfType(typeof(UnityEngine.EventSystems.EventSystem)) == null) { var es = new GameObject(); es.AddComponent <UnityEngine.EventSystems.EventSystem>(); es.AddComponent <UnityEngine.EventSystems.StandaloneInputModule>(); es.name = "EventSystem"; } GameObject canvasObj = null; Canvas canvas = Object.FindObjectOfType(typeof(Canvas)) as Canvas; if (canvas != null) { canvasObj = canvas.gameObject; } else { canvasObj = UIUtility.CreateCanvas().gameObject; } Transform directorT = director.gameObject.transform; directorT.SetParent(canvasObj.transform); directorT.localPosition = new Vector3(0.0f, 0.0f, 0.0f); GameObject imageGo = null; Transform imageT = directorT.Find(strFootageName); if (null == imageT) { imageGo = new GameObject(strFootageName); imageT = imageGo.transform; } else { imageGo = imageT.gameObject; } Image image = imageGo.GetOrAddComponent <Image>(); StreamingImageSequenceRenderer renderer = imageGo.GetOrAddComponent <StreamingImageSequenceRenderer>(); RectTransform rectTransform = imageGo.GetComponent <RectTransform>(); rectTransform.SetParent(directorT); rectTransform.localPosition = new Vector3(0.0f, 0.0f, 0.0f); rectTransform.sizeDelta = new Vector2(footageInfo.Resolution.Width, footageInfo.Resolution.Height); director.SetGenericBinding(movieTrack, renderer); EditorUtility.SetDirty(director); } //cause crash if this is called inside of OnImportAsset() UnityEditor.EditorApplication.delayCall += () => { AssetDatabase.Refresh(); if (null != director) { Selection.activeGameObject = director.gameObject; } }; }