public static void CreateTimeline(string strJsTimelinePath, AssetImportContext ctx = null) { string strUnityPorjectFolder = null; Regex regAssetFolder = new Regex("/Assets$"); strUnityPorjectFolder = Application.dataPath; strUnityPorjectFolder = regAssetFolder.Replace(strUnityPorjectFolder, ""); // prepare paths var strFolderName = Path.GetDirectoryName(strJsTimelinePath); var strAssetName = Path.GetFileNameWithoutExtension(strJsTimelinePath); var strGuid = AssetDatabase.CreateFolder("Assets", strAssetName); var strNewFolderPath = AssetDatabase.GUIDToAssetPath(strGuid); /* * var strMaterialFolder = Path.Combine(strNewFolderPath, "Material"); * if (!Directory.Exists(strMaterialFolder)) * { * Directory.CreateDirectory(strMaterialFolder); * }*/ // create working folder var strJson = File.ReadAllText(strJsTimelinePath); var container = JsonUtility.FromJson <TimelineParam>(strJson); string strAssetFolder = null; if (container.assetFolder == "" || container.assetFolder == null) { strAssetFolder = strFolderName; } var strAssetPath = AssetDatabase.GenerateUniqueAssetPath(Path.Combine(strNewFolderPath, strAssetName + "_Timeline.playable")); TimelineAsset asset = ScriptableObject.CreateInstance <TimelineAsset>(); AssetDatabase.CreateAsset(asset, strAssetPath); var directorGo = new GameObject(strAssetName); var director = directorGo.AddComponent <PlayableDirector>(); director.playableAsset = asset; var 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(strAssetFolder, strFootagePath); } string strFootageName = Path.GetFileNameWithoutExtension(strFootagePath); string strJsonFootage = File.ReadAllText(strFootagePath); StreamingImageSequencePlayableAssetParam trackMovieContainer = JsonUtility.FromJson <StreamingImageSequencePlayableAssetParam>(strJsonFootage); if (trackMovieContainer.Pictures.Length != 0) { // remove '~' if necessary for (int xx = 0; xx < trackMovieContainer.Pictures.Length; xx++) { string filename = trackMovieContainer.Pictures[xx]; if (!filename.StartsWith("~")) { continue; } string newFileName = strHome + filename.Substring(1); trackMovieContainer.Pictures[xx] = newFileName; } var strDir = trackMovieContainer.Pictures[0]; strDir = Path.GetDirectoryName(strDir); for (int xx = 0; xx < trackMovieContainer.Pictures.Length; xx++) { var strFileName = Path.GetFileName(trackMovieContainer.Pictures[xx]); trackMovieContainer.Pictures[xx] = strFileName; } string strStreamingAssets = "Assets/StreamingAssets"; string strDstFolder = Application.streamingAssetsPath; if (!Directory.Exists(strDstFolder)) { Directory.CreateDirectory(strDstFolder); } strDstFolder = Path.Combine(strDstFolder, strFootageName).Replace("\\", "/"); if (!Directory.Exists(strDstFolder)) { Directory.CreateDirectory(strDstFolder); } for (int ii = 0; ii < trackMovieContainer.Pictures.Length; ii++) { string strAbsFilePathDst = Path.Combine(strDstFolder, trackMovieContainer.Pictures[ii]).Replace("\\", "/"); if (File.Exists(strAbsFilePathDst)) { File.Delete(strAbsFilePathDst); } string strAbsFilePathSrc = Path.Combine(strDir, trackMovieContainer.Pictures[ii]).Replace("\\", "/"); FileUtil.CopyFileOrDirectory(strAbsFilePathSrc, strAbsFilePathDst); } trackMovieContainer.Folder = Path.Combine(strStreamingAssets, strFootageName).Replace("\\", "/"); } var proxyAsset = ScriptableObject.CreateInstance <StreamingImageSequencePlayableAsset>(); proxyAsset.SetParam(trackMovieContainer); proxyAsset.m_displayOnClipsOnly = true; var strProxyPath = AssetDatabase.GenerateUniqueAssetPath(Path.Combine(strNewFolderPath, strFootageName + "_MovieProxy.playable")); AssetDatabase.CreateAsset(proxyAsset, strProxyPath); var movieTrack = asset.CreateTrack <MovieProxyTrack>(null, strFootageName); var clip = movieTrack.CreateDefaultClip(); clip.asset = proxyAsset; clip.start = track.Start; clip.duration = track.Duration; 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 = new GameObject(); canvas = canvasObj.AddComponent <Canvas>(); canvas.renderMode = RenderMode.ScreenSpaceOverlay; canvasObj.AddComponent <UnityEngine.UI.CanvasScaler>(); canvasObj.AddComponent <GraphicRaycaster>(); canvasObj.name = "Canvas"; } directorGo.transform.SetParent(canvasObj.transform); directorGo.transform.localPosition = new Vector3(0.0f, 0.0f, 0.0f); var newGo = new GameObject(); Image image = newGo.AddComponent <Image>(); var rectTransform = newGo.GetComponent <RectTransform>(); rectTransform.SetParent(directorGo.transform); rectTransform.localPosition = new Vector3(0.0f, 0.0f, 0.0f); rectTransform.sizeDelta = new Vector2(trackMovieContainer.Resolution.Width, trackMovieContainer.Resolution.Height); newGo.name = strFootageName; newGo.SetActive(true); director.SetGenericBinding(movieTrack, newGo); } if (ctx == null) { AssetDatabase.Refresh(); // cause crash if this is called inside of OnImportAsset() UnityEditor.EditorApplication.delayCall += () => { Selection.activeGameObject = directorGo; }; } }
//--------------------------------------------------------------------------------------------------------------------- /// <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); StreamingImageSequencePlayableAssetParam trackMovieContainer = JsonUtility.FromJson <StreamingImageSequencePlayableAssetParam>(strJsonFootage); int numImages = trackMovieContainer.Pictures.Count; if (numImages > 0) { List <string> originalImagePaths = new List <string>(trackMovieContainer.Pictures); for (int xx = 0; xx < numImages; ++xx) { string fileName = trackMovieContainer.Pictures[xx]; // replace '~' with the path to home (for Linux environment if (fileName.StartsWith("~")) { fileName = strHome + fileName.Substring(1); } trackMovieContainer.Pictures[xx] = Path.GetFileName(fileName); } string destFootageFolder = Application.streamingAssetsPath; destFootageFolder = Path.Combine(destFootageFolder, strFootageName).Replace("\\", "/"); Directory.CreateDirectory(destFootageFolder); //make sure the directory exists trackMovieContainer.Folder = AssetEditorUtility.NormalizeAssetPath(destFootageFolder); for (int i = 0; i < numImages; ++i) { string destFilePath = Path.Combine(destFootageFolder, trackMovieContainer.Pictures[i]); if (File.Exists(destFilePath)) { File.Delete(destFilePath); } string srcFilePath = Path.GetFullPath(Path.Combine(assetFolder, originalImagePaths[i])).Replace("\\", "/"); FileUtil.CopyFileOrDirectory(srcFilePath, destFilePath); } } StreamingImageSequencePlayableAsset sisAsset = ScriptableObject.CreateInstance <StreamingImageSequencePlayableAsset>(); sisAsset.InitFolder(trackMovieContainer); 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(trackMovieContainer.Resolution.Width, trackMovieContainer.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; } }; }
public static void Import(PictureFileImporterParam param) { if (param.DoNotCopy) { param.strDstFolder = param.strSrcFolder.Replace("\\", "/"); } else { string dstFolder = param.strDstFolder.Replace("\\", "/"); if (param.mode == PictureFileImporterParam.Mode.StreamingAssets) { if (dstFolder.StartsWith(Application.dataPath) && !dstFolder.StartsWith(Path.Combine(Application.dataPath, "StreamingAssets").Replace("\\", "/"))) { Debug.LogError("Files must be located under StreamingAssets folder."); return; } } else { if (dstFolder.StartsWith(Application.dataPath) && dstFolder.StartsWith(Path.Combine(Application.dataPath, "StreamingAssets").Replace("\\", "/"))) { Debug.LogError("Files must not be located under StreamingAssets folder."); return; } } foreach (string relPath in param.RelativeFilePaths) { string strAbsFilePathDst = Path.Combine(param.strDstFolder, relPath).Replace("\\", "/"); if (File.Exists(strAbsFilePathDst)) { File.Delete(strAbsFilePathDst); } string strAbsFilePathSrc = Path.Combine(param.strSrcFolder, relPath).Replace("\\", "/"); Directory.CreateDirectory(Path.GetDirectoryName(strAbsFilePathDst));//make sure dir exists FileUtil.CopyFileOrDirectory(strAbsFilePathSrc, strAbsFilePathDst); } } // create assets StreamingImageSequencePlayableAssetParam trackMovieContainer = new StreamingImageSequencePlayableAssetParam(); trackMovieContainer.Pictures = new string[param.RelativeFilePaths.Count]; for (int ii = 0; ii < param.RelativeFilePaths.Count; ii++) { trackMovieContainer.Pictures[ii] = param.RelativeFilePaths[ii]; } /// if possible, convert folder names to relative path. string strUnityProjectFolder = null; Regex regAssetFolder = new Regex("/Assets$"); strUnityProjectFolder = Application.dataPath; strUnityProjectFolder = regAssetFolder.Replace(strUnityProjectFolder, ""); if (param.strDstFolder.StartsWith(strUnityProjectFolder)) { int start = strUnityProjectFolder.Length + 1; int end = param.strDstFolder.Length - start; param.strDstFolder = param.strDstFolder.Substring(start, end); } trackMovieContainer.Folder = param.strDstFolder; if (param.mode == PictureFileImporterParam.Mode.SpriteAnimation) { Sprite[] sprites = new Sprite[param.RelativeFilePaths.Count]; for (int ii = 0; ii < param.RelativeFilePaths.Count; ii++) { string strAssetPath = Path.Combine(param.strDstFolder, param.RelativeFilePaths[ii]).Replace("\\", "/"); AssetDatabase.ImportAsset(strAssetPath); TextureImporter importer = AssetImporter.GetAtPath(strAssetPath) as TextureImporter; importer.textureType = TextureImporterType.Sprite; AssetDatabase.WriteImportSettingsIfDirty(strAssetPath); Texture2D tex = (Texture2D)AssetDatabase.LoadAssetAtPath(strAssetPath, typeof(Texture2D)); sprites[ii] = Sprite.Create(tex, new Rect(0.0f, 0.0f, tex.width, tex.height), new Vector2(0.5f, 0.5f)); } AnimationClip newClip = new AnimationClip(); newClip.wrapMode = WrapMode.Once; SerializedObject serializedClip = new SerializedObject(newClip); SerializedProperty settings = serializedClip.FindProperty("m_AnimationClipSettings"); while (settings.Next(true)) { if (settings.name == "m_LoopTime") { break; } } settings.boolValue = true; serializedClip.ApplyModifiedProperties(); ObjectReferenceKeyframe[] Keyframes = new ObjectReferenceKeyframe[param.RelativeFilePaths.Count]; EditorCurveBinding curveBinding = new EditorCurveBinding(); for (int ii = 0; ii < param.RelativeFilePaths.Count; ii++) { Keyframes[ii] = new ObjectReferenceKeyframe(); Keyframes[ii].time = 0.25F * ii; Keyframes[ii].value = sprites[ii]; } #if false curveBinding.type = typeof(SpriteRenderer); curveBinding.path = string.Empty; curveBinding.propertyName = "m_Sprite"; #else curveBinding.type = typeof(Image); curveBinding.path = string.Empty; curveBinding.propertyName = "m_Sprite"; #endif AnimationUtility.SetObjectReferenceCurve(newClip, curveBinding, Keyframes); AssetDatabase.CreateAsset(newClip, Path.Combine(param.strDstFolder, "Animation.anim").Replace("\\", "/")); // var proxyAsset = ScriptableObject.CreateInstance<StreamingImageSequencePlayableAsset>(); //new StreamingImageSequencePlayableAsset(trackMovieContainer); // proxyAsset.SetParam(trackMovieContainer); // var strProxyPath = AssetDatabase.GenerateUniqueAssetPath(Path.Combine("Assets", param.strAssetName + "_MovieProxy.playable").Replace("\\", "/"));*/ AssetDatabase.Refresh(); } else { //StreamingAsset StreamingImageSequencePlayableAsset proxyAsset = param.TargetAsset; if (null == proxyAsset) { proxyAsset = ScriptableObject.CreateInstance <StreamingImageSequencePlayableAsset>(); var strProxyPath = AssetDatabase.GenerateUniqueAssetPath(Path.Combine("Assets", param.strAssetName + "_MovieProxy.playable").Replace("\\", "/")); AssetDatabase.CreateAsset(proxyAsset, strProxyPath); } proxyAsset.SetParam(trackMovieContainer); if (!param.DoNotCopy) { AssetDatabase.Refresh(); } } }
//---------------------------------------------------------------------------------------------------------------------- internal static void Import(ImageFileImporterParam param) { string destFolder = null; if (!param.CopyToStreamingAssets) { destFolder = param.strSrcFolder.Replace("\\", "/"); } else { destFolder = param.strDstFolder.Replace("\\", "/"); if (destFolder.StartsWith(Application.dataPath) && !destFolder.StartsWith(Path.Combine(Application.dataPath, "StreamingAssets").Replace("\\", "/"))) { Debug.LogError("Files must be located under StreamingAssets folder."); return; } foreach (string relPath in param.RelativeFilePaths) { string strAbsFilePathDst = Path.Combine(destFolder, relPath).Replace("\\", "/"); if (File.Exists(strAbsFilePathDst)) { File.Delete(strAbsFilePathDst); } string strAbsFilePathSrc = Path.Combine(param.strSrcFolder, relPath).Replace("\\", "/"); Directory.CreateDirectory(Path.GetDirectoryName(strAbsFilePathDst));//make sure dir exists FileUtil.CopyFileOrDirectory(strAbsFilePathSrc, strAbsFilePathDst); } } // create assets StreamingImageSequencePlayableAssetParam playableAssetParam = new StreamingImageSequencePlayableAssetParam(); playableAssetParam.Pictures = new List <string>(param.RelativeFilePaths); //if possible, convert folder names to relative path. string strUnityProjectFolder = null; Regex regAssetFolder = new Regex("/Assets$"); strUnityProjectFolder = Application.dataPath; strUnityProjectFolder = regAssetFolder.Replace(strUnityProjectFolder, ""); if (destFolder.StartsWith(strUnityProjectFolder)) { int start = strUnityProjectFolder.Length + 1; int end = destFolder.Length - start; destFolder = destFolder.Substring(start, end); } playableAssetParam.Folder = destFolder; //StreamingAsset StreamingImageSequencePlayableAsset playableAsset = param.TargetAsset; if (null == playableAsset) { string assetName = ImageSequenceImporter.EstimateAssetName(playableAssetParam.Pictures[0]); playableAsset = CreateUniqueSISAsset( Path.Combine("Assets", assetName + "_StreamingImageSequence.playable").Replace("\\", "/") ); } playableAsset.InitFolder(playableAssetParam); if (param.CopyToStreamingAssets) { AssetDatabase.Refresh(); } }