Пример #1
0
        private void OnEnable()
        {
            Selection.selectionChanged -= HandleSelectionChange;
            Selection.selectionChanged += HandleSelectionChange;

            stylesLoaded       = false;
            isAdvancedMode     = EditorPrefs.GetBool(PrefKeyAdvancedMode, false);
            typeImportUserData = typeof(ImportUserData);
            serializer         = new fsSerializer();

            // Find implementations of IReconstructor
            var type  = typeof(IReconstructor);
            var types = AppDomain.CurrentDomain.GetAssemblies()
                        .SelectMany(s => s.GetTypes())
                        .Where(p => p != type && type.IsAssignableFrom(p));

            List <IReconstructor> constructor_list     = new List <IReconstructor>();
            List <GUIContent>     constructor_dropdown = new List <GUIContent>();

            foreach (Type type_constructor in types)
            {
                var instance   = Activator.CreateInstance(type_constructor);
                var r_instance = (IReconstructor)instance;
                if (r_instance != null)
                {
                    constructor_list.Add(r_instance);
                    constructor_dropdown.Add(new GUIContent(r_instance.DisplayName));
                }
            }

            reconstructors      = constructor_list.ToArray();
            dropdownReconstruct = constructor_dropdown.ToArray();
            importSettings      = new ImportUserData();
        }
Пример #2
0
        public static void Reconstruct(Object psdFile, ImportUserData importSettings,
                                       ImportLayerData reconstructRoot, Vector2 documentPivot,
                                       IReconstructor reconstructor)
        {
            string psdPath = GetPsdFilepath(psdFile);

            if (string.IsNullOrEmpty(psdPath))
            {
                return;
            }

            using (var psdDoc = PsdDocument.Create(psdPath))
            {
                ReconstructData data = GetReconstructData(psdDoc, psdPath,
                                                          documentPivot, importSettings,
                                                          reconstructRoot);

                var GO = reconstructor.Reconstruct(reconstructRoot, data, Selection.activeGameObject);
                if (GO != null)
                {
                    EditorGUIUtility.PingObject(GO);
                    Selection.activeGameObject = GO;
                }
            }
        }
Пример #3
0
        private static Sprite ImportLayer(PsdDocument psdDoc, ImportUserData importSettings, ImportLayerData layerSettings, TextureImporterSettings psdUnityImport)
        {
            if (layerSettings == null)
            {
                return(null);
            }

            PsdLayer psdLayer = GetPsdLayerByIndex(psdDoc, layerSettings.indexId);

            if (psdLayer.IsGroup)
            {
                return(null);
            }

            // Generate the texture
            Texture2D layerTexture = GetLayerTexture(psdDoc, psdLayer, layerSettings);

            if (layerTexture == null)
            {
                return(null);
            }

            // Save the texture as an asset
            Sprite layerSprite = SaveAsset(psdLayer, psdUnityImport, layerTexture, importSettings, layerSettings);

            return(layerSprite);
        }
Пример #4
0
        private static Sprite CreateSpriteAsset(PsdDocument psdDoc, ImportUserData importSettings, ImportLayerData layerSettings, TextureImporterSettings psdUnityImport)
        {
            if (layerSettings == null)
            {
                return(null);
            }

            PsdLayer psdLayer = GetPsdLayerByIndex(psdDoc, layerSettings.indexId);

            if (psdLayer.IsGroup)
            {
                return(null);
            }

            // Generate the texture
            Texture2D layerTexture = GetLayerTexture(psdDoc, psdLayer, layerSettings.ScaleFactor);

            if (layerTexture == null)
            {
                return(null);
            }

            var layerPath = PathUtils.GetLayerPath(psdLayer, importSettings.fileNaming, importSettings.groupMode);

            // Save the texture as an asset
            return(SaveAsset(layerPath, psdUnityImport, layerTexture, importSettings.TargetDirectory, importSettings.PackingTag, layerSettings));
        }
Пример #5
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);
        }
Пример #6
0
        public static string GetFilePath(PsdLayer layer, ImportUserData importSettings, string format, out string dir)
        {
            string filename = string.Format("{0}.{1}", layer.Name, format);

            string folder = "";

            if (importSettings.fileNaming != NamingConvention.LayerNameOnly)
            {
                bool isDir    = importSettings.fileNaming == NamingConvention.CreateGroupFolders;
                var  docLayer = layer.Document as IPsdLayer;
                var  parent   = layer.Parent;
                while (parent != null && parent.Equals(docLayer) == false)
                {
                    if (isDir)
                    {
                        if (string.IsNullOrEmpty(folder))
                        {
                            folder = parent.Name;
                        }
                        else
                        {
                            folder = string.Format("{0}/{1}", parent.Name, folder);
                        }
                    }
                    else
                    {
                        filename = string.Format("{0}_{1}", parent.Name, filename);
                    }
                    parent = parent.Parent;
                    if (importSettings.groupMode == GroupMode.ParentOnly)
                    {
                        break;
                    }
                }
            }

            string finalDir = importSettings.TargetDirectory;

            if (string.IsNullOrEmpty(folder) == false)
            {
                finalDir = string.Format("{0}/{1}", finalDir, folder);
            }
            // Sanitize directory
            finalDir = SanitizeString(finalDir, Path.GetInvalidPathChars());

            // Sanitize filename
            filename = SanitizeString(filename, Path.GetInvalidFileNameChars());

            string filepath = string.Format("{0}/{1}", finalDir, filename);

            dir = finalDir;
            return(filepath);
        }
Пример #7
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
                );
        }
Пример #8
0
        private static ReconstructData GetReconstructData(PsdDocument psdDoc, string psdPath, Vector2 documentPivot,
                                                          ImportUserData importSettings, ImportLayerData reconstructRoot)
        {
            // Get the texture import setting of the PSD
            TextureImporter         psdUnitySettings = (TextureImporter)AssetImporter.GetAtPath(psdPath);
            TextureImporterSettings psdUnityImport   = new TextureImporterSettings();

            psdUnitySettings.ReadTextureSettings(psdUnityImport);

            Vector2         docSize = new Vector2(psdDoc.Width, psdDoc.Height);
            ReconstructData data    = new ReconstructData(docSize, documentPivot, psdUnitySettings.spritePixelsPerUnit);

            reconstructRoot.Iterate(
                layerCallback: layer =>
            {
                if (layer.import == false)
                {
                    return;
                }

                var psdLayer = GetPsdLayerByIndex(psdDoc, layer.indexId);

                Rect layerBounds = new Rect()
                {
                    xMin = psdLayer.Left,
                    xMax = psdLayer.Right,
                    yMin = psdDoc.Height - psdLayer.Bottom,
                    yMax = psdDoc.Height - psdLayer.Top
                };
                data.layerBoundsIndex.Add(layer.indexId, layerBounds);

                string layerDir;
                string layerPath = GetFilePath(psdLayer, importSettings, "png", out layerDir);

                string layerMeshDir;
                string layerMeshPath = GetFilePath(psdLayer, importSettings, "asset", out layerMeshDir);

                Sprite layerSprite         = AssetDatabase.LoadAssetAtPath <Sprite>(layerPath);
                SpriteMesh layerSpriteMesh = AssetDatabase.LoadAssetAtPath <SpriteMesh>(layerMeshPath);

                if (layerSprite == null)
                {
                    layerSprite = ImportLayer(psdDoc, importSettings, layer, psdUnityImport);
                }

                if (layerSpriteMesh == null && importSettings.GenerateSpriteMesh)
                {
                    layerSpriteMesh = GenerateSpriteMesh(layerSprite);
                }

                Vector2 spriteAnchor = Vector2.zero;

                if (layerSprite != null)
                {
                    TextureImporter layerImporter         = (TextureImporter)AssetImporter.GetAtPath(layerPath);
                    TextureImporterSettings layerSettings = new TextureImporterSettings();
                    layerImporter.ReadTextureSettings(layerSettings);

                    if (layerSettings.spriteAlignment == (int)SpriteAlignment.Custom)
                    {
                        spriteAnchor = layerSettings.spritePivot;
                    }
                    else
                    {
                        spriteAnchor = AlignmentToPivot((SpriteAlignment)layerSettings.spriteAlignment);
                    }
                }

                data.AddSprite(layer.indexId, layerSprite, spriteAnchor);

                if (importSettings.GenerateSpriteMesh)
                {
                    data.AddSpriteMesh(layer.indexId, layerSpriteMesh);
                }
            },
                canEnterGroup: checkGroup => checkGroup.import
                );

            return(data);
        }
Пример #9
0
        private static Sprite SaveAsset(PsdLayer psdLayer, TextureImporterSettings psdUnityImport,
                                        Texture2D texture, ImportUserData importSettings, ImportLayerData layerSettings)
        {
            // Generate the file path for this layer
            string fileDir;
            string filepath = GetFilePath(psdLayer, importSettings, "png", out fileDir);

            // Create the folder if non existent
            if (AssetDatabase.IsValidFolder(fileDir) == false)
            {
                var    subPaths     = fileDir.Split('/');
                string parentFolder = subPaths[0];
                foreach (string folder in subPaths.Skip(1))
                {
                    string targetFolder = string.Format("{0}/{1}", parentFolder, folder);
                    if (AssetDatabase.IsValidFolder(targetFolder) == false)
                    {
                        AssetDatabase.CreateFolder(parentFolder, folder);
                    }
                    parentFolder = targetFolder;
                }
            }

            // Write out the texture contents into the file
            AssetDatabase.CreateAsset(texture, filepath);
            byte[] buf = texture.EncodeToPNG();
            File.WriteAllBytes(filepath, buf);

            AssetDatabase.ImportAsset(filepath, ImportAssetOptions.ForceUpdate);
            Texture2D textureObj = AssetDatabase.LoadAssetAtPath <Texture2D>(filepath);

            // Get the texture importer for the asset
            TextureImporter textureImporter = (TextureImporter)AssetImporter.GetAtPath(filepath);
            // Read out the texture import settings so settings can be changed
            TextureImporterSettings texSetting = new TextureImporterSettings();

            textureImporter.ReadTextureSettings(texSetting);

            float finalPPU = psdUnityImport.spritePixelsPerUnit;

            switch (layerSettings.ScaleFactor)
            {
            case ScaleFactor.Half:
                finalPPU /= 2;
                break;

            case ScaleFactor.Quarter:
                finalPPU /= 4;
                break;
            }

            // Change settings
            texSetting.spriteAlignment     = (int)layerSettings.Alignment;
            texSetting.spritePivot         = layerSettings.Pivot;
            texSetting.spritePixelsPerUnit = finalPPU;
            texSetting.filterMode          = psdUnityImport.filterMode;
            texSetting.wrapMode            = psdUnityImport.wrapMode;
            texSetting.textureType         = TextureImporterType.Sprite;
            texSetting.spriteMode          = (int)SpriteImportMode.Single;
            texSetting.mipmapEnabled       = false;
            texSetting.alphaIsTransparency = true;
            texSetting.npotScale           = TextureImporterNPOTScale.None;
            // Set the rest of the texture settings
            textureImporter.spritePackingTag = importSettings.PackingTag;
            // Write in the texture import settings
            textureImporter.SetTextureSettings(texSetting);

            EditorUtility.SetDirty(textureObj);
            AssetDatabase.WriteImportSettingsIfDirty(filepath);
            AssetDatabase.ImportAsset(filepath, ImportAssetOptions.ForceUpdate);
            return((Sprite)AssetDatabase.LoadAssetAtPath(filepath, typeof(Sprite)));
        }
Пример #10
0
        private static IEnumerator ImportCoroutine(Object psdFile, ImportUserData importSettings,
                                                   List <int[]> layerIndices, bool doYield     = false,
                                                   Action <int, ImportLayerData> layerCallback = null,
                                                   Action <List <Sprite> > completeCallback    = null)
        {
            string filepath = GetPsdFilepath(psdFile);

            if (string.IsNullOrEmpty(filepath))
            {
                if (completeCallback != null)
                {
                    completeCallback(null);
                }
                yield break;
            }

            // No target directory set, use PSD file directory
            if (string.IsNullOrEmpty(importSettings.TargetDirectory))
            {
                importSettings.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;

            List <Sprite> sprites = new List <Sprite>();

            using (PsdDocument psd = PsdDocument.Create(filepath))
            {
                foreach (int[] layerIdx in layerIndices)
                {
                    ImportLayerData layerSettings = importSettings.GetLayerData(layerIdx);
                    if (layerSettings == null)
                    {
                        continue;
                    }

                    if (layerCallback != null)
                    {
                        layerCallback(importCurrent, layerSettings);
                    }

                    var sprite = ImportLayer(psd, importSettings, layerSettings, psdUnityImport);

                    if (importSettings.GenerateSpriteMesh)
                    {
                        GenerateSpriteMesh(sprite);
                    }

                    sprites.Add(sprite);
                    importCurrent++;

                    if (doYield)
                    {
                        yield return(null);
                    }
                }
            }
            if (completeCallback != null)
            {
                completeCallback(sprites);
            }
        }
Пример #11
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)
         );
 }
Пример #12
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);
                    }
                })
                    );
            }
        }
Пример #13
0
        public void OpenFile(Object fileObject)
        {
            if (isOpeningFile)
            {
                return;
            }

            importFile    = null;
            importPath    = string.Empty;
            importPreview = null;
            importPPU     = 100;

            importSettings = new ImportUserData()
            {
                DocAlignment = SpriteAlignment.Center
            };
            importDisplay = null;

            selectionCount = 0;
            quickSelect.Clear();
            lastSelectedLayer = null;

            var filePath = AssetDatabase.GetAssetPath(fileObject);

            if (filePath.ToLower().EndsWith(".psd") == false)
            {
                return;
            }

            importFile    = fileObject;
            importPath    = filePath;
            importPreview = AssetDatabase.LoadAssetAtPath <Texture2D>(importPath);

            // Read the texture import settings of the asset file
            TextureImporter         textureImporter     = (TextureImporter)AssetImporter.GetAtPath(importPath);
            TextureImporterSettings unityImportSettings = new TextureImporterSettings();

            textureImporter.ReadTextureSettings(unityImportSettings);

            importPPU = unityImportSettings.spritePixelsPerUnit;

            // Attempt to deserialize
            string json           = textureImporter.userData;
            bool   didGetUserData = false;

            if (string.IsNullOrEmpty(json) == false)
            {
                fsData data        = fsJsonParser.Parse(json);
                object deserialObj = null;
                if (serializer.TryDeserialize(data, typeImportUserData, ref deserialObj)
                    .AssertSuccessWithoutWarnings()
                    .Succeeded)
                {
                    importSettings = (ImportUserData)deserialObj;
                    if (importSettings == null)
                    {
                        importSettings = new ImportUserData();
                    }
                    else
                    {
                        didGetUserData = true;
                    }
                }
            }

            if (didGetUserData)
            {
                settingsChanged = false;
            }
            else
            {
                settingsChanged    = true;
                showImportSettings = true;
            }

            isOpeningFile = true;
            PsdImporter.BuildImportLayerData(importFile, importSettings, (layerData, displayData) =>
            {
                importSettings.DocRoot = ResolveData(importSettings.DocRoot, layerData);

                importDisplay = displayData;
                isOpeningFile = false;
                CollateImportList();
                Repaint();
            });
        }
Пример #14
0
        private static IList <Texture2D> CreateTextures2D(IList <PsdLayerWithScaleFactor> psdLayer, PsdDocument psdDoc, ImportUserData importSettings, TextureImporterSettings psdUnityImport)
        {
            var result = new List <Texture2D>();

            foreach (var layer in psdLayer)
            {
                // Generate the texture
                Texture2D layerTexture = GetLayerTexture(psdDoc, layer.psdLayer, layer.scaleFactor);
                if (layerTexture == null)
                {
                    continue;
                }

                result.Add(layerTexture);
            }

            return(result);
        }
Пример #15
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);
        }