public static void ImportLayersUI(Object psdFile, ImportUserData importSettings, List <int[]> layerIndices) { int total = layerIndices.Count; Action <int, ImportLayerData> layerCallback = (current, layer) => EditorCoroutineRunner.UpdateUI($"[{current}/{total}] Layer: {layer.name}", (float)current / total); IEnumerator importCoroutine = ImportCoroutine(psdFile, importSettings.TargetDirectory, importSettings, layerIndices, layerCallback); EditorCoroutineRunner.StartCoroutineWithUI(importCoroutine, "Importing PSD Layers", true); }
public static void ImportLayersUI(Object psdFile, ImportUserData importSettings, List <int[]> layerIndices) { int total = layerIndices.Count; EditorCoroutineRunner.StartCoroutineWithUI( ImportCoroutine(psdFile, importSettings, layerIndices, true, layerCallback: (current, layer) => { string text = string.Format("[{0}/{1}] Layer: {2}", current, total, layer.name); float percent = (float)current / total; EditorCoroutineRunner.UpdateUI(text, percent); } ), "Importing PSD Layers", true ); }
private static IEnumerator ParseLayers(IPsdLayer[] layers, bool doYield, Action <PsdLayer, int[]> onLayer, Action onComplete, int[] parentIndex = null) { // Loop through layers in reverse so they are encountered in same order as Photoshop for (int i = layers.Length - 1; i >= 0; i--) { int[] layerIndex = parentIndex; if (layerIndex == null) { layerIndex = new int[] { i }; } else { int lastIndex = layerIndex.Length; Array.Resize(ref layerIndex, lastIndex + 1); layerIndex[lastIndex] = i; } PsdLayer layer = layers[i] as PsdLayer; if (layer == null) { continue; } if (onLayer != null) { onLayer(layer, layerIndex); } if (doYield) { yield return(null); } if (layer.Childs.Length > 0) { yield return(EditorCoroutineRunner.StartCoroutine( ParseLayers(layer.Childs, doYield, onLayer, null, layerIndex) )); } } if (onComplete != null) { onComplete(); } }
public void Tick() { if (coroutine != null) { // First check if we have been canceled by the UI. If so, we need to stop before doing any wait processing if (canceled) { Stop(); return; } // Did the last Yield want us to wait? bool isWaiting = false; var now = DateTime.Now; if (current != null) { if (currentType == typeof(WaitForSeconds)) { // last yield was a WaitForSeconds. Lets update the timer. var delta = now - lastUpdateTime; timer -= (float)delta.TotalSeconds; if (timer > 0.0f) { isWaiting = true; } } else if (currentType == typeof(WaitForEndOfFrame) || currentType == typeof(WaitForFixedUpdate)) { // These dont make sense in editor, so we will treat them the same as a null return... isWaiting = false; } else if (currentType == typeof(WWW)) { // Web download request, lets see if its done! var www = current as WWW; if (!www.isDone) { isWaiting = true; } } else if (currentType.IsSubclassOf(typeof(CustomYieldInstruction))) { // last yield was a custom yield type, lets check its keepWaiting property and react to that var yieldInstruction = current as CustomYieldInstruction; if (yieldInstruction.keepWaiting) { isWaiting = true; } } else if (currentType == typeof(EditorCoroutine)) { // Were waiting on another coroutine to finish var editorCoroutine = current as EditorCoroutine; if (!editorCoroutine.HasFinished) { isWaiting = true; } } else if (typeof(IEnumerator).IsAssignableFrom(currentType)) { // if were just seeing an enumerator lets assume that were seeing a nested coroutine that has been passed in without calling start.. were start it properly here if we need to if (nestedCoroutine == null) { nestedCoroutine = EditorCoroutineRunner.StartCoroutine(current as IEnumerator); isWaiting = true; } else { isWaiting = !nestedCoroutine.HasFinished; } } else if (currentType == typeof(Coroutine)) { // UNSUPPORTED Debug.LogError("Nested Coroutines started by Unity's defaut StartCoroutine method are not supported in editor! please use EditorCoroutineRunner.Start instead. Canceling."); canceled = true; } else { // UNSUPPORTED Debug.LogError("Unsupported yield (" + currentType + ") in editor coroutine!! Canceling."); canceled = true; } } lastUpdateTime = now; // have we been canceled? if (canceled) { Stop(); return; } if (!isWaiting) { // nope were good! tick the coroutine! bool update = coroutine.MoveNext(); if (update) { // yup the coroutine returned true so its been ticked... // lets see what it actually yielded current = coroutine.Current; if (current != null) { // is it a type we have to do extra processing on? currentType = current.GetType(); if (currentType == typeof(WaitForSeconds)) { // its a WaitForSeconds... lets use reflection to pull out how long the actual wait is for so we can process the wait var wait = current as WaitForSeconds; FieldInfo m_Seconds = typeof(WaitForSeconds).GetField("m_Seconds", BindingFlags.NonPublic | BindingFlags.Instance); if (m_Seconds != null) { timer = (float)m_Seconds.GetValue(wait); } } else if (currentType == typeof(EditorStatusUpdate)) { // Special case yield that wants to update the UI! var updateInfo = current as EditorStatusUpdate; if (updateInfo.HasLabelUpdate) { Label = updateInfo.Label; } if (updateInfo.HasPercentUpdate) { PercentComplete = updateInfo.PercentComplete; } } } } else { // Coroutine returned false so its finally finished!! Stop(); } } } }
public static void ImportLayers(Object psdFile, ImportUserData importSettings, List <int[]> layerIndices, Action <List <Sprite> > callback = null) { EditorCoroutineRunner.StartCoroutine( ImportCoroutine(psdFile, importSettings, layerIndices, false, completeCallback: callback) ); }
public static void BuildImportLayerData(Object file, ImportUserData importSettings, Action <ImportLayerData, DisplayLayerData> callback) { string filepath = GetPsdFilepath(file); if (string.IsNullOrEmpty(filepath)) { if (callback != null) { callback(null, null); } return; } using (PsdDocument psd = PsdDocument.Create(filepath)) { ImportLayerData docImportData = new ImportLayerData() { name = DOC_ROOT, indexId = new int[] { -1 }, Childs = new List <ImportLayerData>() }; DisplayLayerData docDisplayData = new DisplayLayerData() { indexId = new int[] { -1 }, Childs = new List <DisplayLayerData>() }; EditorCoroutineRunner.StartCoroutine( ParseLayers(psd.Childs, false, onLayer: (layer, indexId) => { // Walk down the index id to get the parent layers // and build the full path string fullPath = ""; ImportLayerData parentLayer = docImportData; DisplayLayerData parentDisplay = docDisplayData; if (indexId.Length > 1) { for (int idIdx = 0; idIdx < indexId.Length - 1; idIdx++) { int idx = indexId[idIdx]; parentLayer = parentLayer.Childs[idx]; parentDisplay = parentDisplay.Childs[idx]; if (string.IsNullOrEmpty(fullPath) == false) { fullPath += "/"; } fullPath += parentLayer.name; } } if (string.IsNullOrEmpty(fullPath) == false) { fullPath += "/"; } fullPath += layer.Name; ImportLayerData layerImportData = new ImportLayerData() { name = layer.Name, path = fullPath, indexId = indexId, import = layer.IsVisible, useDefaults = true, Alignment = importSettings.DefaultAlignment, Pivot = importSettings.DefaultPivot, ScaleFactor = importSettings.ScaleFactor, Childs = new List <ImportLayerData>() }; DisplayLayerData layerDisplayData = new DisplayLayerData() { indexId = indexId, isVisible = layer.IsVisible, isGroup = layer.Childs.Length > 0, isOpen = layer.IsFolderOpen }; int layerIdx = indexId[indexId.Length - 1]; int maxLayers = layerIdx + 1; while (parentLayer.Childs.Count < maxLayers) { parentLayer.Childs.Add(null); } parentLayer.Childs[layerIdx] = layerImportData; while (parentDisplay.Childs.Count < maxLayers) { parentDisplay.Childs.Add(null); } parentDisplay.Childs[layerIdx] = layerDisplayData; }, onComplete: () => { if (callback != null) { callback(docImportData, docDisplayData); } }) ); } }
private static IEnumerator ImportCoroutine(Object psdFile, string targetDirectory, ImportUserData importSettings, List <int[]> layerIndices, Action <int, ImportLayerData> layerCallback = null, Action <List <Sprite> > completeCallback = null) { string filepath = GetPsdFilepath(psdFile); if (string.IsNullOrEmpty(filepath)) { completeCallback?.Invoke(null); yield break; } if (string.IsNullOrEmpty(targetDirectory)) { targetDirectory = filepath.Substring(0, filepath.LastIndexOf("/")); } // Get the texture importer for the PSD TextureImporter psdUnitySettings = (TextureImporter)AssetImporter.GetAtPath(filepath); TextureImporterSettings psdUnityImport = new TextureImporterSettings(); psdUnitySettings.ReadTextureSettings(psdUnityImport); int importCurrent = 0; var sprites = new List <Sprite>(); using (PsdDocument psd = PsdDocument.Create(filepath)) { var layersSettings = new List <ImportLayerData>(); foreach (int[] layerIdx in layerIndices) { ImportLayerData layerSettings = importSettings.GetLayerData(layerIdx); if (layerSettings == null) { continue; } layerCallback?.Invoke(importCurrent, layerSettings); layersSettings.Add(layerSettings); } const float totalSteps = 4.0f; float currentStep = 0.0f; EditorCoroutineRunner.UpdateUI($"Getting psd layers", ++currentStep / totalSteps); yield return(null); var psdLayers = GetPsdLayers(layersSettings, psd); EditorCoroutineRunner.UpdateUI($"CreateTextures2D", ++currentStep / totalSteps); yield return(null); var textures = CreateTextures2D(psdLayers, psd, importSettings, psdUnityImport); EditorCoroutineRunner.UpdateUI($"GetTextureWithPathData", ++currentStep / totalSteps); yield return(null); var texturesData = GetTextureWithPathData(textures, psdLayers.Select(x => x.psdLayer).ToArray(), importSettings.fileNaming, importSettings.groupMode, targetDirectory); EditorCoroutineRunner.UpdateUI($"CreateSpriteAssets", ++currentStep / totalSteps); yield return(null); sprites.AddRange(CreateSpriteAssets(texturesData, layersSettings, psdUnityImport, importSettings.PackingTag)); } completeCallback?.Invoke(sprites); }