Пример #1
0
        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);
        }
Пример #2
0
        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
                );
        }
Пример #3
0
        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();
            }
        }
Пример #4
0
        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();
                    }
                }
            }
        }
Пример #5
0
 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)
         );
 }
Пример #6
0
        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);
                    }
                })
                    );
            }
        }
Пример #7
0
        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);
        }