diff --git a/.buginfo b/.buginfo new file mode 100644 index 0000000..12dcb2e --- /dev/null +++ b/.buginfo @@ -0,0 +1 @@ +package: 2D PSD Importer diff --git a/CHANGELOG.md b/CHANGELOG.md index a1f9200..befcb34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,14 @@ # Changelog + +## [9.0.2] - 2024-02-06 +### Fixed +- Provide custom packing override for users to override to address DANB-526. (Case DANB-526) +- Fixed layers are not shown in LayerImportSettings after unselecting all layers and applying. (Case DANB-569) + ## [9.0.1] - 2023-08-15 ### Fixed - Fixed case where PSDImporter does not support the PVRTC compression format for the iOS platform. (Case DANB-500) +- Provide custom packing override for users to override to address DANB-526. (Case DANB-526) ## [9.0.0] - 2023-02-23 ### Fixed @@ -254,4 +261,4 @@ - Handles include or exclude hidden layers - Supports Prefab generation that reconstruct generated Sprites to original art asset layout - Prefab generation supports GameObject grouping based on Adobe Photoshop layer grouping -- Supports 2D Animation v2 single character with multiple Sprites workflow +- Supports 2D Animation v2 single character with multiple Sprites workflow \ No newline at end of file diff --git a/Editor/PSDImportData.cs b/Editor/PSDImportData.cs index 0af40db..6cfb94f 100644 --- a/Editor/PSDImportData.cs +++ b/Editor/PSDImportData.cs @@ -17,7 +17,7 @@ public int importedTextureWidth get => m_ImportedTextureWidth; set => m_ImportedTextureWidth = value; } - + [SerializeField] int m_ImportedTextureHeight; public int importedTextureHeight @@ -25,7 +25,7 @@ public int importedTextureHeight get => m_ImportedTextureHeight; set => m_ImportedTextureHeight = value; } - + [SerializeField] Vector2Int m_DocumentSize; public Vector2Int documentSize @@ -52,11 +52,7 @@ public int textureActualWidth [SerializeField] PSDLayerData[] m_PsdLayerData; - public PSDLayerData[] psdLayerData - { - get => m_PsdLayerData; - set => m_PsdLayerData = value; - } + public PSDLayerData[] psdLayerData => m_PsdLayerData; public void CreatePSDLayerData(List bitmapLayer) { @@ -103,7 +99,7 @@ class PSDLayerImportSetting: IPSDLayerMappingStrategyComparable [SerializeField] string m_SpriteId; GUID m_SpriteIDGUID; - + public string name; public int layerId; public bool flatten; @@ -113,7 +109,7 @@ class PSDLayerImportSetting: IPSDLayerMappingStrategyComparable public int layerID => layerId; string IPSDLayerMappingStrategyComparable.name => name; bool IPSDLayerMappingStrategyComparable.isGroup => isGroup; - + public GUID spriteId { get @@ -134,7 +130,7 @@ public GUID spriteId } } } - + /// /// PSDLayer data for PSDImportData for last import state /// @@ -180,7 +176,7 @@ public bool isGroup get => m_IsGroup; set => m_IsGroup = value; } - + [SerializeField] bool m_IsImported; public bool isImported @@ -196,10 +192,10 @@ public Vector2Int layerSizeOnFile get => m_LayerSizeOnFile; set => m_LayerSizeOnFile = value; } - + } - + /// /// Data for extracting layers and colors from PSD /// @@ -209,5 +205,4 @@ class PSDExtractLayerData public PSDLayerImportSetting importSetting; public PSDExtractLayerData[] children; } -} - +} \ No newline at end of file diff --git a/Editor/PSDImporter.cs b/Editor/PSDImporter.cs index c207a7f..37876e4 100644 --- a/Editor/PSDImporter.cs +++ b/Editor/PSDImporter.cs @@ -5,6 +5,7 @@ using UnityEngine; using Unity.Collections; using System.Linq; +using System.Reflection; using UnityEditor.AssetImporters; using UnityEditor.U2D.Common; using UnityEditor.U2D.Sprites; @@ -103,7 +104,7 @@ internal enum ELayerMappingOption [SerializeField] List m_LayeredSpriteImportData = new List(); // --- Obsolete sprite import data containers - + // SpriteData for both single and multiple mode [Obsolete("This data has now been merged into m_MultiSpriteImportData and m_SingleSpriteImportData")] [SerializeField] List m_SpriteImportData = new List(); // we use index 0 for single sprite and the rest for multiple sprites @@ -115,7 +116,7 @@ internal enum ELayerMappingOption [SerializeField] List m_SharedRigSpriteImportData = new List(); [Obsolete("This data has now been merged into m_LayeredSpriteImportData")] [SerializeField] List m_MosaicSpriteImportData = new List(); - + // --- End obsolete sprite import data containers #if ENABLE_2D_ANIMATION @@ -123,7 +124,7 @@ internal enum ELayerMappingOption [SerializeField] CharacterData m_SharedRigCharacterData = new CharacterData(); // CharacterData for Rig mode [SerializeField] CharacterData m_CharacterData = new CharacterData(); -#endif +#endif [SerializeField] List m_PlatformSettings = new List(); @@ -150,17 +151,22 @@ internal enum ELayerMappingOption [SerializeField] int m_Padding = 4; - + [SerializeField] ushort m_SpriteSizeExpand = 0; - - [SerializeField] + + [SerializeField] string m_SkeletonAssetReferenceID = null; - -#if ENABLE_2D_ANIMATION + + [SerializeField] + ScriptableObject m_Pipeline; + [SerializeField] + string m_PipelineVersion; + +#if ENABLE_2D_ANIMATION [SerializeField] SpriteCategoryList m_SpriteCategoryList = new SpriteCategoryList() {categories = new List()}; -#endif +#endif GameObjectCreationFactory m_GameObjectFactory = new GameObjectCreationFactory(null); @@ -174,10 +180,10 @@ internal PSDImportData importData if (returnValue == null && !PSDImporterAssetPostProcessor.ContainsImporter(this)) // Using LoadAllAssetsAtPath because PSDImportData is hidden returnValue = AssetDatabase.LoadAllAssetsAtPath(assetPath).FirstOrDefault(x => x is PSDImportData) as PSDImportData; - + if (returnValue == null) returnValue = ScriptableObject.CreateInstance(); - + m_ImportData = returnValue; return returnValue; } @@ -186,7 +192,7 @@ internal PSDImportData importData internal int textureActualWidth { get => importData.textureActualWidth; - private set =>importData.textureActualWidth = value; + private set =>importData.textureActualWidth = value; } internal int textureActualHeight @@ -200,29 +206,29 @@ internal int textureActualHeight [SerializeField] bool m_ResliceFromLayer = false; - + [SerializeField] PSDLayerImportSetting[] m_PSDLayerImportSetting; - [SerializeField] + [SerializeField] List m_PsdLayers = new List(); - - // --- Obsolete psd layer containers - + + // --- Obsolete psd layer containers + [Obsolete("This data has now been merged into m_PsdLayers")] [SerializeField] List m_MosaicPSDLayers = new List(); [Obsolete("This data has now been merged into m_PsdLayers")] [SerializeField] List m_RigPSDLayers = new List(); [Obsolete("This data has now been merged into m_PsdLayers")] [SerializeField] List m_SharedRigPSDLayers = new List(); - + // --- End obsolete psd layer containers - + // Use for inspector to check if the file node is checked [SerializeField] #pragma warning disable 169, 414 bool m_ImportFileNodeState = true; - + // Used by platform settings to mark it dirty so that it will trigger a reimport [SerializeField] #pragma warning disable 169, 414 @@ -230,7 +236,7 @@ internal int textureActualHeight [SerializeField] bool m_SpriteSizeExpandChanged = false; - + [SerializeField] bool m_GenerateGOHierarchy = false; @@ -242,21 +248,21 @@ internal int textureActualHeight [SerializeField] string m_SpriteLibAssetName = null; - + [SerializeField] string m_SkeletonAssetName = null; [SerializeField] SecondarySpriteTexture[] m_SecondarySpriteTextures; - + PSDExtractLayerData[] m_ExtractData; - + internal bool isNPOT => Mathf.IsPowerOfTwo(importData.textureActualWidth) && Mathf.IsPowerOfTwo(importData.textureActualHeight); - + bool shouldProduceGameObject => m_CharacterMode && m_MosaicLayers && spriteImportModeToUse == SpriteImportMode.Multiple; bool shouldResliceFromLayer => m_ResliceFromLayer && m_MosaicLayers && spriteImportModeToUse == SpriteImportMode.Multiple; bool inCharacterMode => inMosaicMode && m_CharacterMode; - + float definitionScale { get @@ -265,8 +271,8 @@ float definitionScale var definitionScaleH = importData.importedTextureHeight / (float)textureActualHeight; return Mathf.Min(definitionScaleW, definitionScaleH); } - } - + } + internal SecondarySpriteTexture[] secondaryTextures { get => m_SecondarySpriteTextures; @@ -277,14 +283,14 @@ internal SpriteBone[] mainSkeletonBones { get { -#if ENABLE_2D_ANIMATION +#if ENABLE_2D_ANIMATION var skeleton = skeletonAsset; return skeleton != null ? skeleton.GetSpriteBones() : null; #else return null; -#endif +#endif } - } + } /// /// PSDImporter constructor. @@ -297,6 +303,30 @@ public PSDImporter() m_TextureImporterSettings.swizzleB = TextureImporterSwizzle.B; } + void PackImage(NativeArray[] buffers, int[] width, int[] height, int padding, uint spriteSizeExpand, out NativeArray outPackedBuffer, out int outPackedBufferWidth, out int outPackedBufferHeight, out RectInt[] outPackedRect, out Vector2Int[] outUVTransform, bool requireSquarePOT = false) + { + try + { + ScriptableObject pipeline = m_Pipeline; + if(pipeline == null) + pipeline = AssetDatabase.LoadAssetAtPath("Packages/com.unity.2d.psdimporter/Editor/Pipeline.asset"); + + var args = new object[] { buffers, width, height, padding, spriteSizeExpand, null, 0, 0, null, null, requireSquarePOT }; + pipeline.GetType().InvokeMember("PackImage", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.InvokeMethod | BindingFlags.Static, null, + pipeline, args); + outPackedBuffer = (NativeArray)args[5]; + outPackedBufferWidth = (int)args[6]; + outPackedBufferHeight = (int)args[7]; + outPackedRect = (RectInt[])args[8]; + outUVTransform = (Vector2Int[])args[9]; + } + catch (Exception e) + { + Debug.LogError("Unable to pack image. ex:"+e.ToString(), this); + ImagePacker.Pack(buffers, width, height, padding, spriteSizeExpand, out outPackedBuffer, out outPackedBufferWidth, out outPackedBufferHeight, out outPackedRect, out outUVTransform, requireSquarePOT); + } + } + /// /// Implementation of ScriptedImporter.OnImportAsset /// @@ -306,13 +336,14 @@ public PSDImporter() /// public override void OnImportAsset(AssetImportContext ctx) { + var fileStream = new FileStream(ctx.assetPath, FileMode.Open, FileAccess.Read); Document doc = null; - + if(m_ImportData == null) m_ImportData = ScriptableObject.CreateInstance(); m_ImportData.hideFlags = HideFlags.HideInHierarchy; - + try { UnityEngine.Profiling.Profiler.BeginSample("OnImportAsset"); @@ -320,9 +351,9 @@ public override void OnImportAsset(AssetImportContext ctx) UnityEngine.Profiling.Profiler.BeginSample("PsdLoad"); doc = PaintDotNet.Data.PhotoshopFileType.PsdLoad.Load(fileStream); UnityEngine.Profiling.Profiler.EndSample(); - + m_ImportData.CreatePSDLayerData(doc.Layers); - + ValidatePSDLayerId(doc, m_LayerMappingOption); SetDocumentImportData(doc); @@ -339,7 +370,7 @@ public override void OnImportAsset(AssetImportContext ctx) { output = ImportFromLayers(ctx); } - + if (output.texture != null && output.sprites != null) SetPhysicsOutline(GetDataProvider(), output.sprites, definitionScale, pixelsPerUnit, m_GeneratePhysicsShape); @@ -368,7 +399,7 @@ void ValidatePSDLayerId(Document doc, ELayerMappingOption layerMappingOption) ImportUtilities.ValidatePSDLayerId(GetPSDLayers(), doc.Layers, uniqueNameGenerator); } } - + TextureGenerationOutput ImportTexture(AssetImportContext ctx, NativeArray imageData, int textureWidth, int textureHeight, SpriteMetaData[] sprites) { if (!imageData.IsCreated || imageData.Length == 0) @@ -390,7 +421,7 @@ TextureGenerationOutput ImportTexture(AssetImportContext ctx, NativeArray layers, PSDExtractLayerData[ { flatten = c.flatten, importLayer = layer.Visible || m_ImportHiddenLayers, - }; + }; } importSetting.spriteId = c.spriteID; } - + if (importSetting == null) { importSetting = new PSDLayerImportSetting() { flatten = false, importLayer = layer.Visible || m_ImportHiddenLayers, - }; + }; } - + extractData[i] = new PSDExtractLayerData() { bitmapLayer = layer, importSetting = importSetting, }; - + PSDExtractLayerData[] childrenExtractData = null; if (layer.ChildLayer != null) { @@ -498,7 +529,7 @@ void SetDocumentImportData(IEnumerable layers, PSDExtractLayerData[ extractData[i].children = childrenExtractData; } } - + void SetDocumentImportData(Document doc) { var oldPsdLayers = GetPSDLayers(); @@ -506,7 +537,7 @@ void SetDocumentImportData(Document doc) m_ExtractData = new PSDExtractLayerData[doc.Layers.Count]; SetDocumentImportData(doc.Layers, m_ExtractData, mappingStrategy, oldPsdLayers); } - + TextureGenerationOutput ImportFlattenImage(Document doc, AssetImportContext ctx) { TextureGenerationOutput output; @@ -520,7 +551,7 @@ TextureGenerationOutput ImportFlattenImage(Document doc, AssetImportContext ctx) m_SingleSpriteImportData[0].border = m_TextureImporterSettings.spriteBorder; m_SingleSpriteImportData[0].pivot = m_TextureImporterSettings.spritePivot; m_SingleSpriteImportData[0].rect = new Rect(0, 0, doc.width, doc.height); - + importData.importedTextureWidth = textureActualWidth = doc.width; importData.importedTextureHeight = textureActualHeight = doc.height; @@ -536,7 +567,7 @@ TextureGenerationOutput ImportFlattenImage(Document doc, AssetImportContext ctx) return output; } - + TextureGenerationOutput ImportFromLayers(AssetImportContext ctx) { TextureGenerationOutput output; @@ -553,7 +584,7 @@ TextureGenerationOutput ImportFromLayers(AssetImportContext ctx) try { ExtractLayerTask.Execute(in m_ExtractData, out psdLayers, m_ImportHiddenLayers, canvasSize); - + var mappingStrategy = GetLayerMappingStrategy(); var layerUnique = mappingStrategy.LayersUnique(psdLayers.ConvertAll(x => (IPSDLayerMappingStrategyComparable)x)); if (!string.IsNullOrEmpty(layerUnique)) @@ -598,8 +629,8 @@ TextureGenerationOutput ImportFromLayers(AssetImportContext ctx) } } - ImagePacker.Pack(layerBuffers.ToArray(), layerWidth.ToArray(), layerHeight.ToArray(), m_Padding, m_SpriteSizeExpand, out outputImageBuffer, out int width, out int height, out RectInt[] spriteData, out Vector2Int[] uvTransform, requireSquarePOT); - + PackImage(layerBuffers.ToArray(), layerWidth.ToArray(), layerHeight.ToArray(), m_Padding, m_SpriteSizeExpand, out outputImageBuffer, out int width, out int height, out RectInt[] spriteData, out Vector2Int[] uvTransform, requireSquarePOT); + var packOffsets = new Vector2[spriteData.Length]; for (var i = 0; i < packOffsets.Length; ++i) packOffsets[i] = new Vector2((uvTransform[i].x - spriteData[i].position.x) / -1f, (uvTransform[i].y - spriteData[i].position.y) / -1f); @@ -628,14 +659,14 @@ TextureGenerationOutput ImportFromLayers(AssetImportContext ctx) r.position = r.position - psdLayer.mosaicPosition + spriteData[i].position; spriteSheet.rect = r; } - + psdLayer.spriteName = ImportUtilities.GetUniqueSpriteName(psdLayer.name, spriteNameHash, m_KeepDupilcateSpriteName); spriteSheet.name = psdLayer.spriteName; spriteSheet.spritePosition = psdLayer.layerPosition + packOffsets[i]; - + if(shouldResliceFromLayer) spriteSheet.rect = new Rect(spriteData[i].x, spriteData[i].y, spriteData[i].width, spriteData[i].height); - + spriteSheet.uvTransform = uvTransform[i]; psdLayer.spriteID = spriteSheet.spriteID; @@ -698,13 +729,13 @@ TextureGenerationOutput ImportFromLayers(AssetImportContext ctx) { var r = spriteSheet.rect; r.position = spriteSheet.rect.position - psdLayers[i].mosaicPosition + spriteData[k].position; - + if (inOldLayer && (m_SpriteSizeExpand > 0 || m_SpriteSizeExpandChanged)) { r.width = spriteData[k].width; r.height = spriteData[k].height; } - + spriteSheet.rect = r; spriteSheet.spritePosition = psdLayers[i].layerPosition + packOffsets[k]; } @@ -725,7 +756,7 @@ TextureGenerationOutput ImportFromLayers(AssetImportContext ctx) oldPsdLayers.AddRange(psdLayers); importData.importedTextureHeight = textureActualHeight = height; importData.importedTextureWidth = textureActualWidth = width; - + output = ImportTexture(ctx, outputImageBuffer, width, height, spriteImportData.ToArray()); if (output.texture) { @@ -751,15 +782,15 @@ internal void MigrateOlderData() } void MigrateOlderSpriteImportData() - { + { // Suppressing Obsolete warning, as this method migrate data from those obsolete containers. #pragma warning disable 0618 - var hasMigratedData = m_LayeredSpriteImportData.Count > 0 || - m_MultiSpriteImportData.Count > 0 || + var hasMigratedData = m_LayeredSpriteImportData.Count > 0 || + m_MultiSpriteImportData.Count > 0 || !ImportUtilities.IsSpriteMetaDataDefault(m_SingleSpriteImportData[0]); if (hasMigratedData) return; - + if (inCharacterMode) { if (!string.IsNullOrEmpty(m_SkeletonAssetReferenceID) && m_SharedRigSpriteImportData.Count > 0) @@ -777,7 +808,7 @@ void MigrateOlderSpriteImportData() if (m_SpriteImportData.Count > 1) m_MultiSpriteImportData = m_SpriteImportData.GetRange(1, m_SpriteImportData.Count - 1); } -#pragma warning restore 0618 +#pragma warning restore 0618 } void MigrateOlderPsdLayerData() @@ -787,7 +818,7 @@ void MigrateOlderPsdLayerData() var hasMigratedData = m_PsdLayers.Count > 0; if (hasMigratedData) return; - + if (inCharacterMode) { if (!string.IsNullOrEmpty(m_SkeletonAssetReferenceID) && m_SharedRigPSDLayers.Count > 0) @@ -803,6 +834,7 @@ void MigrateOlderPsdLayerData() void RegisterAssets(AssetImportContext ctx, TextureGenerationOutput output) { + ctx.AddObjectToAsset("PSDImportData", m_ImportData); if ((output.sprites == null || output.sprites.Length == 0) && output.texture == null) { Debug.LogWarning(TextContent.noSpriteOrTextureImportWarning, this); @@ -834,8 +866,6 @@ void RegisterAssets(AssetImportContext ctx, TextureGenerationOutput output) RegisterGameObjects(ctx, output, ref mainAsset); RegisterSprites(ctx, output, assetNameGenerator); RegisterSkeletonAsset(ctx, output, assetName); - - ctx.AddObjectToAsset("PSDImportData", m_ImportData); ctx.SetMainObject(mainAsset); } @@ -850,14 +880,14 @@ void RegisterTextureAsset(AssetImportContext ctx, TextureGenerationOutput output void RegisterSpriteLibraryAsset(AssetImportContext ctx, TextureGenerationOutput output, string assetName) { -#if ENABLE_2D_ANIMATION +#if ENABLE_2D_ANIMATION if (output.sprites == null) return; - + var slAsset = ProduceSpriteLibAsset(output.sprites); if (slAsset == null) return; - + slAsset.name = assetName; var spriteLibAssetNameId = string.IsNullOrEmpty(m_SpriteLibAssetName) ? "SpriteLibAsset" : m_SpriteLibAssetName; ctx.AddObjectToAsset(spriteLibAssetNameId, slAsset); @@ -873,13 +903,13 @@ void RegisterGameObjects(AssetImportContext ctx, TextureGenerationOutput output, var prefabRootNameId = string.IsNullOrEmpty(m_TextureAssetName) ? "root" : m_TextureAssetName; var registerPrefabNameId = string.IsNullOrEmpty(m_PrefabAssetName) ? "Prefab" : m_PrefabAssetName; - + GameObject prefab = null; if (m_PaperDollMode) prefab = OnProducePaperDollPrefab(ctx, prefabRootNameId, output.sprites); else prefab = OnProducePrefab(ctx, prefabRootNameId, output.sprites); - + if (prefab != null) { ctx.AddObjectToAsset(registerPrefabNameId, prefab); @@ -891,17 +921,17 @@ void RegisterSprites(AssetImportContext ctx, TextureGenerationOutput output, Uni { if (output.sprites == null) return; - + foreach (var s in output.sprites) { var spriteAssetName = assetNameGenerator.GetUniqueName(s.GetSpriteID().ToString(), false, s); ctx.AddObjectToAsset(spriteAssetName, s); - } + } } void RegisterSkeletonAsset(AssetImportContext ctx, TextureGenerationOutput output, string assetName) { -#if ENABLE_2D_ANIMATION +#if ENABLE_2D_ANIMATION var skeletonAssetNameId = string.IsNullOrEmpty(m_SkeletonAssetName) ? "SkeletonAsset" : m_SkeletonAssetName; if (output.sprites != null) @@ -915,7 +945,7 @@ void RegisterSkeletonAsset(AssetImportContext ctx, TextureGenerationOutput outpu ctx.AddObjectToAsset(skeletonAssetNameId, characterRig); } } - + if (!string.IsNullOrEmpty(m_SkeletonAssetReferenceID)) { var primaryAssetPath = AssetDatabase.GUIDToAssetPath(m_SkeletonAssetReferenceID); @@ -923,7 +953,7 @@ void RegisterSkeletonAsset(AssetImportContext ctx, TextureGenerationOutput outpu { ctx.DependsOnArtifact(primaryAssetPath); } - } + } #endif } @@ -937,7 +967,7 @@ void BuildGroupGameObject(List psdGroup, int index, Transform root) if (spriteImported || isVisibleGroup) { var spriteData = GetSpriteImportData().FirstOrDefault(x => x.spriteID == psdData.spriteID); -#if ENABLE_2D_ANIMATION +#if ENABLE_2D_ANIMATION // Determine if need to create GameObject i.e. if the sprite is not in a SpriteLib or if it is the first one var shouldCreateGo = ImportUtilities.SpriteIsMainFromSpriteLib(m_SpriteCategoryList.categories, psdData.spriteID.ToString(), out var categoryName); var goName = string.IsNullOrEmpty(categoryName) ? spriteData != null ? spriteData.name : psdData.name : categoryName; @@ -983,12 +1013,12 @@ void CreateBoneGO(int index, SpriteBone[] bones, BoneGO[] bonesGO, Transform def { go = go, index = index - }; + }; } BoneGO[] CreateBonesGO(Transform root) { -#if ENABLE_2D_ANIMATION +#if ENABLE_2D_ANIMATION if (inCharacterMode) { var characterSkeleton = GetDataProvider().GetCharacterData(); @@ -1011,8 +1041,8 @@ void GetSpriteLibLabel(string spriteId, out string category, out string label) { category = ""; label = ""; - -#if ENABLE_2D_ANIMATION + +#if ENABLE_2D_ANIMATION foreach (var cat in m_SpriteCategoryList.categories) { var index = cat.labels.FindIndex(x => x.spriteId == spriteId); @@ -1033,19 +1063,19 @@ GameObject OnProducePaperDollPrefab(AssetImportContext ctx, string assetName, Sp { root = new GameObject(); root.name = assetName + "_GO"; - -#if ENABLE_2D_ANIMATION + +#if ENABLE_2D_ANIMATION var spriteImportData = GetSpriteImportData(); var psdLayers = GetPSDLayers(); var boneGOs = CreateBonesGO(root.transform); - + var contextObjects = new List(); ctx.GetObjects(contextObjects); var spriteLib = contextObjects.Find(x => x.GetType() == typeof(SpriteLibraryAsset)) as SpriteLibraryAsset; - + if (spriteLib != null) root.AddComponent().spriteLibraryAsset = spriteLib; - + var currentCharacterData = characterData; for (var i = 0; i < sprites.Length; ++i) { @@ -1111,8 +1141,8 @@ GameObject OnProducePrefab(AssetImportContext ctx, string assetname, Sprite[] sp root = new GameObject(); root.transform.SetSiblingIndex(0); root.name = assetname + "_GO"; - -#if ENABLE_2D_ANIMATION + +#if ENABLE_2D_ANIMATION var currentCharacterData = characterData; var contextObjects = new List(); @@ -1121,9 +1151,9 @@ GameObject OnProducePrefab(AssetImportContext ctx, string assetname, Sprite[] sp if (spriteLib != null) root.AddComponent().spriteLibraryAsset = spriteLib; - + CharacterData? characterSkeleton = inCharacterMode ? new CharacterData ? (GetDataProvider().GetCharacterData()) : null; -#endif +#endif var psdLayers = GetPSDLayers(); for (var i = 0; i < psdLayers.Count; ++i) @@ -1142,7 +1172,7 @@ GameObject OnProducePrefab(AssetImportContext ctx, string assetname, Sprite[] sp var spriteRenderer = l.gameObject.AddComponent(); spriteRenderer.sprite = sprite; spriteRenderer.sortingOrder = psdLayers.Count - i; - + var pivot = spriteMetaData.pivot; pivot.x *= spriteMetaData.rect.width; pivot.y *= spriteMetaData.rect.height; @@ -1151,7 +1181,7 @@ GameObject OnProducePrefab(AssetImportContext ctx, string assetname, Sprite[] sp spritePosition.x += pivot.x; spritePosition.y += pivot.y; spritePosition *= (definitionScale / sprite.pixelsPerUnit); - + l.gameObject.transform.position = new Vector3(spritePosition.x, spritePosition.y, 0f); #if ENABLE_2D_ANIMATION @@ -1293,8 +1323,8 @@ internal void SetDocumentPivot(Vector2 pivot) (SpriteImportMode)m_TextureImporterSettings.spriteMode; internal Vector2Int canvasSize => importData.documentSize; - -#if ENABLE_2D_ANIMATION + +#if ENABLE_2D_ANIMATION internal CharacterData characterData { get @@ -1344,7 +1374,7 @@ internal void ReadTextureSettings(TextureImporterSettings dest) { m_TextureImporterSettings.CopyTo(dest); } - + internal IPSDLayerMappingStrategy GetLayerMappingStrategy() { return m_MappingCompare[(int)m_LayerMappingOption]; @@ -1398,4 +1428,4 @@ static void SetPhysicsOutline(ISpritePhysicsOutlineDataProvider physicsOutlineDa } } } -} +} \ No newline at end of file diff --git a/Editor/PSDImporterEditor.cs b/Editor/PSDImporterEditor.cs index 379ecfb..32a62f7 100644 --- a/Editor/PSDImporterEditor.cs +++ b/Editor/PSDImporterEditor.cs @@ -80,17 +80,17 @@ struct InspectorGUI SerializedProperty m_Padding; SerializedProperty m_SpriteSizeExpand; SerializedProperty m_SpriteSizeExpandChanged; - -#if ENABLE_2D_ANIMATION + +#if ENABLE_2D_ANIMATION SerializedProperty m_PaperDollMode; SerializedProperty m_SkeletonAssetReferenceID; #endif - + uint m_SpriteSizePreviousSize; - + readonly int[] m_FilterModeOptions = (int[])(Enum.GetValues(typeof(FilterMode))); static readonly int s_SwizzleFieldHash = "SwizzleField".GetHashCode(); - + bool m_IsPOT = false; Dictionary m_AdvanceInspectorGUI = new Dictionary(); int m_PlatformSettingsIndex; @@ -98,7 +98,7 @@ struct InspectorGUI int m_ActiveEditorIndex = 0; TexturePlatformSettingsHelper m_TexturePlatformSettingsHelper; - + PSDImporterEditorFoldOutState m_EditorFoldOutState = new PSDImporterEditorFoldOutState(); InspectorGUI[] m_InspectorUI; PSDImporter m_CurrentTarget; @@ -114,11 +114,12 @@ struct InspectorGUI ScrollView m_InspectorScrollView; int m_LayerTreeViewUpdateCount = 0; SerializedProperty m_PlatformSettingsArrProp; - + SerializedProperty m_Pipeline; + #if ENABLE_2D_ANIMATION SkeletonAsset m_SkeletonAsset; #endif - + /// /// Implementation of AssetImporterEditor.OnEnable /// @@ -139,7 +140,8 @@ public override void OnEnable() m_SpriteSizeExpand = serializedObject.FindProperty("m_SpriteSizeExpand"); m_SpriteSizePreviousSize = m_SpriteSizeExpand.uintValue; m_SpriteSizeExpandChanged = serializedObject.FindProperty("m_SpriteSizeExpandChanged"); - + m_Pipeline = serializedObject.FindProperty("m_Pipeline"); + var textureImporterSettingsSP = serializedObject.FindProperty("m_TextureImporterSettings"); m_TextureType = textureImporterSettingsSP.FindPropertyRelative("m_TextureType"); m_TextureShape = textureImporterSettingsSP.FindPropertyRelative("m_TextureShape"); @@ -195,7 +197,8 @@ public override void OnEnable() POTScaleGUI, ReadableGUI, MipMapGUI, - SwizzleGUI + SwizzleGUI, + CustomPipelineGUI, }; m_AdvanceInspectorGUI.Add(TextureImporterType.Sprite, advanceGUIAction); @@ -204,19 +207,20 @@ public override void OnEnable() POTScaleGUI, ReadableGUI, MipMapGUI, - SwizzleGUI + SwizzleGUI, + CustomPipelineGUI, }; m_AdvanceInspectorGUI.Add(TextureImporterType.Default, advanceGUIAction); - + m_TexturePlatformSettingsHelper = new TexturePlatformSettingsHelper(this); - + m_InspectorUI = new [] { new InspectorGUI() { container = new IMGUIContainer(DoInspectorSettings) { - name = "DoSettingsUI" + name = "DoSettingsUI" }, needsRepaint = false, }, @@ -235,11 +239,19 @@ public override void OnEnable() InitPreview(); } + void CustomPipelineGUI() + { + if (Unsupported.IsDeveloperMode()) + { + EditorGUILayout.PropertyField(m_Pipeline); + } + } + /// /// Override for AssetImporter.extraDataType /// protected override Type extraDataType => typeof(PSDImporterEditorExternalData); - + /// /// Override for AssetImporter.InitializeExtraDataInstance /// @@ -254,15 +266,15 @@ protected override void InitializeExtraDataInstance(UnityEngine.Object extraTarg { extraData.Init(importer, platformSettingsNeeded); } - + } - + void OnLayerManagementUIUpdate() { if (m_LayerManagementTreeView != null) m_LayerManagementTreeView.Update(); } - + void OnLayerManagementViewActivated() { if(serializedObject.isEditingMultipleObjects) @@ -278,7 +290,7 @@ void OnLayerManagementViewActivated() m_LayerManagementSettingsContainer.SetHiddenFromLayout(false); } } - + VisualElement CreateLayerManagementUI() { var ve = new VisualElement(); @@ -296,13 +308,13 @@ VisualElement CreateLayerManagementUI() flexShrink = 0 } }; - + m_LayerManagementTreeView = new PSDImporterLayerManagementMultiColumnTreeView(serializedObject) { name = "LayerManagementTreeView" }; m_LayerManagementTreeView.RegisterCallback(OnTreeViewAttachedToPanel); - + m_ApplyRevertGUIVisualElement = new IMGUIContainer(ApplyRevertGUIVisualElement) { name = "LayerManagementApplyRevertGUI", @@ -319,7 +331,7 @@ VisualElement CreateLayerManagementUI() ve.Add(m_ApplyRevertGUIVisualElement); return ve; } - + void OnTreeViewAttachedToPanel(AttachToPanelEvent evt) { m_InspectorScrollView = m_RootVisualElement.panel.visualTree.Q(); @@ -340,14 +352,14 @@ void UpdateLayerTreeViewHeight() // m_LayerManagementTreeView.MarkDirtyRepaint(); // } } - + void ApplyRevertGUIVisualElement() { serializedObject.ApplyModifiedProperties(); extraDataSerializedObject.ApplyModifiedProperties(); ApplyRevertGUI(); } - + void InitPreview() { var t = (PSDImporter)target; @@ -382,7 +394,7 @@ public override void OnDisable() } if(m_RootVisualElement != null) m_RootVisualElement.Clear(); - + if(m_LayerManagementTreeView != null) m_LayerManagementTreeView.UnregisterCallback(OnTreeViewAttachedToPanel); if(m_ApplyRevertGUIVisualElement != null) @@ -399,7 +411,7 @@ void UpdateLayerTreeView() m_LayerManagementTreeView.UpdateTreeView(serializedObject); } } - + /// /// Override from AssetImporterEditor.RequiresConstantRepaint /// @@ -416,7 +428,7 @@ void DoInspectorSettings() DoSettingsUI(); ApplyRevertGUIVisualElement(); } - + /// /// Implementation of virtual method CreateInspectorGUI. /// @@ -469,7 +481,7 @@ void VisualElementUpdate() extraDataSerializedObject.ApplyModifiedProperties(); m_RootVisualElement.schedule.Execute(VisualElementUpdate); } - + void ShowInspectorTab(int tab) { m_InspectorSettingsView.Clear(); @@ -498,7 +510,7 @@ void DoToolBarIMGUI() GUILayout.Space(5); } - + void DoLayerManagementUI() { EditorGUILayout.PropertyField(m_ImportHiddenLayers, styles.importHiddenLayer); @@ -511,7 +523,7 @@ void DoLayerManagementUI() GUI.Label(headerRect, "Layer Import Settings"); } } - + void DoSettingsUI() { if (m_EditorFoldOutState.DoGeneralUI(styles.generalHeaderText)) @@ -519,7 +531,7 @@ void DoSettingsUI() EditorGUI.showMixedValue = m_TextureType.hasMultipleDifferentValues; m_TextureType.intValue = EditorGUILayout.IntPopup(styles.textureTypeTitle, m_TextureType.intValue, styles.textureTypeOptions, styles.textureTypeValues); EditorGUI.showMixedValue = false; - + switch ((TextureImporterType)m_TextureType.intValue) { case TextureImporterType.Sprite: @@ -545,7 +557,7 @@ void DoSettingsUI() void MainRigPropertyField() { -#if ENABLE_2D_ANIMATION +#if ENABLE_2D_ANIMATION EditorGUI.BeginChangeCheck(); m_SkeletonAsset = EditorGUILayout.ObjectField(styles.mainSkeletonName, m_SkeletonAsset, typeof(SkeletonAsset), false) as SkeletonAsset; if (EditorGUI.EndChangeCheck()) @@ -606,7 +618,7 @@ static PsdColorMode FileColorMode(PsdFile doc) bool IsCharacterRigged() { -#if ENABLE_2D_ANIMATION +#if ENABLE_2D_ANIMATION var importer = target as PSDImporter; if (importer != null) { @@ -632,8 +644,6 @@ bool IsCharacterRigged() void DoPlatformSettings() { - { - } if (m_EditorFoldOutState.DoPlatformSettingsUI(styles.platformSettingsHeaderText)) { GUILayout.Space(5); @@ -910,7 +920,7 @@ void DoSpriteTextureTypeInspector() GUILayout.BeginHorizontal(); EditorGUILayout.PropertyField(m_SpritePivot, new GUIContent()); GUILayout.EndHorizontal(); - } + } } } EditorGUILayout.PropertyField(m_GeneratePhysicsShape, styles.generatePhysicsShape); @@ -922,16 +932,16 @@ void DoSpriteTextureTypeInspector() EditorGUILayout.HelpBox(styles.resliceFromLayerWarning.text, MessageType.Info, true); } } - + DoOpenSpriteEditorButton(); } - + void DoSpriteInspector() { if (m_EditorFoldOutState.DoLayerImportUI(styles.layerImportHeaderText)) { EditorGUILayout.PropertyField(m_ImportHiddenLayers, styles.importHiddenLayer); - + using (new EditorGUI.DisabledScope(m_SpriteMode.intValue != (int)SpriteImportMode.Multiple || m_SpriteMode.hasMultipleDifferentValues)) { using (new EditorGUI.DisabledScope(m_MosaicLayers.boolValue == false)) @@ -942,7 +952,7 @@ void DoSpriteInspector() { EditorGUILayout.PropertyField(m_GenerateGOHierarchy, styles.layerGroupLabel); } - + EditorGUILayout.IntPopup(m_LayerMappingOption, styles.layerMappingOption, styles.layerMappingOptionValues, styles.layerMapping); } @@ -954,14 +964,14 @@ void DoSpriteInspector() using (new EditorGUI.DisabledScope(m_MosaicLayers.boolValue == false)) { EditorGUILayout.IntSlider(m_Padding, 0, 32, styles.padding); - + EditorGUILayout.PropertyField(m_SpriteSizeExpand, styles.spriteSizeExpand); } } GUILayout.Space(5); } -#if ENABLE_2D_ANIMATION +#if ENABLE_2D_ANIMATION if (m_EditorFoldOutState.DoCharacterRigUI(styles.characterRigHeaderText)) { using (new EditorGUI.DisabledScope(m_SpriteMode.intValue != (int)SpriteImportMode.Multiple || m_SpriteMode.hasMultipleDifferentValues || m_MosaicLayers.boolValue == false)) @@ -978,7 +988,7 @@ void DoSpriteInspector() EditorGUILayout.PropertyField(m_DocumentPivot, new GUIContent()); GUILayout.EndHorizontal(); } - } + } } GUILayout.Space(5); //EditorGUILayout.PropertyField(m_PaperDollMode, s_Styles.paperDollMode); @@ -1015,7 +1025,7 @@ void DoOpenSpriteEditorButton() } } GUILayout.EndHorizontal(); - } + } } /// @@ -1032,7 +1042,7 @@ public override void SaveChanges() } ApplyTexturePlatformSettings(); - + serializedObject.ApplyModifiedProperties(); extraDataSerializedObject.ApplyModifiedProperties(); base.SaveChanges(); @@ -1102,7 +1112,7 @@ void MipMapGUI() EditorGUI.indentLevel++; ToggleFromInt(m_BorderMipMap, styles.borderMipMaps); -#if ENABLE_TEXTURE_STREAMING +#if ENABLE_TEXTURE_STREAMING ToggleFromInt(m_StreamingMipmaps, styles.streamingMipMaps); if (m_StreamingMipmaps.boolValue && !m_StreamingMipmaps.hasMultipleDifferentValues) { @@ -1115,8 +1125,8 @@ void MipMapGUI() } EditorGUI.indentLevel--; } -#endif - +#endif + m_MipMapMode.intValue = EditorGUILayout.Popup(styles.mipMapFilter, m_MipMapMode.intValue, styles.mipMapFilterOptions); ToggleFromInt(m_MipMapsPreserveCoverage, styles.mipMapsPreserveCoverage); @@ -1219,7 +1229,7 @@ void SwizzleGUI() { SwizzleField(m_Swizzle, styles.swizzle); } - + /// /// Implementation of AssetImporterEditor.ResetValues. /// @@ -1228,7 +1238,7 @@ protected override void ResetValues() { DiscardChanges(); } - + /// /// Implementation of AssetImporterEditor.DiscardChanges. /// @@ -1337,13 +1347,13 @@ public string GetBuildTargetName(SerializedProperty sp) } /// - /// The SerializedProperty of an array of TextureImporterPlatformSettings. + /// The SerializedProperty of an array of TextureImporterPlatformSettings. /// public SerializedProperty platformSettingsArray => m_PlatformSettingsArrProp; static (TextureImporterSwizzle r, TextureImporterSwizzle g, TextureImporterSwizzle b, TextureImporterSwizzle a) ConvertSwizzleRaw(uint value) { - return ((TextureImporterSwizzle)((int)value & (int)byte.MaxValue), + return ((TextureImporterSwizzle)((int)value & (int)byte.MaxValue), (TextureImporterSwizzle) ((int)(value >> 8) & (int) byte.MaxValue), (TextureImporterSwizzle) ((int)(value >> 16) & (int) byte.MaxValue), (TextureImporterSwizzle) ((int)(value >> 24) & (int) byte.MaxValue)); @@ -1365,7 +1375,7 @@ internal TextureImporterSettings GetSerializedPropertySettings(TextureImporterSe settings.streamingMipmaps = m_StreamingMipmaps.intValue > 0; if (!m_StreamingMipmapsPriority.hasMultipleDifferentValues) settings.streamingMipmapsPriority = m_StreamingMipmapsPriority.intValue; -#endif +#endif if (!m_MipMapsPreserveCoverage.hasMultipleDifferentValues) settings.mipMapsPreserveCoverage = m_MipMapsPreserveCoverage.intValue > 0; @@ -1396,7 +1406,7 @@ internal TextureImporterSettings GetSerializedPropertySettings(TextureImporterSe settings.swizzleB = swizzleValue.b; settings.swizzleA = swizzleValue.a; } - + if (!m_FadeOut.hasMultipleDifferentValues) settings.fadeOut = m_FadeOut.intValue > 0; @@ -1458,7 +1468,7 @@ public override bool showImportedObject { get { return false; } } - + bool ITexturePlatformSettingsDataProvider.textureTypeHasMultipleDifferentValues { get { return m_TextureType.hasMultipleDifferentValues; } @@ -1470,12 +1480,12 @@ TextureImporterType ITexturePlatformSettingsDataProvider.textureType } SpriteImportMode ITexturePlatformSettingsDataProvider.spriteImportMode => spriteImportMode; - + SpriteImportMode spriteImportMode { get { return (SpriteImportMode)m_SpriteMode.intValue; } } - + /// /// Override of AssetImporterEditor.HasModified. /// @@ -1492,7 +1502,7 @@ bool shouldProduceGameObject { get { return m_CharacterMode.boolValue && m_MosaicLayers.boolValue && spriteImportMode == SpriteImportMode.Multiple; } } - + /// /// Override from AssetImporterEditor to show preview settings. /// @@ -1526,7 +1536,7 @@ public override void DrawPreview(Rect r) var t = (PSDImporter)target; var prefabBounds = new Rect(0 , 0, t.importData.documentSize.x/ t.pixelsPerUnit, t.importData.documentSize.y/ t.pixelsPerUnit); var documentPivot = ImportUtilities.GetPivotPoint(prefabBounds, (SpriteAlignment)m_DocumentAlignment.intValue, m_DocumentPivot.vector2Value); - m_PreviewRenderUtility.DrawPreview(r, "PreBackgroundSolid", documentPivot, m_ShowPivot); + m_PreviewRenderUtility.DrawPreview(r, "PreBackgroundSolid", documentPivot, m_ShowPivot); } else base.DrawPreview(r); @@ -1553,7 +1563,7 @@ internal class Styles (int)TextureImporterType.Default, (int)TextureImporterType.Sprite, }; - + private readonly GUIContent textureShape2D = new GUIContent("2D, Texture is 2D."); private readonly GUIContent textureShapeCube = new GUIContent("Cube", "Texture is a Cubemap."); public readonly Dictionary textureShapeOptionsDictionnary = new Dictionary(); @@ -1589,10 +1599,10 @@ internal class Styles public readonly GUIContent generateMipMaps = new GUIContent("Generate Mip Maps"); public readonly GUIContent sRGBTexture = new GUIContent("sRGB (Color Texture)", "Texture content is stored in gamma space. Non-HDR color textures should enable this flag (except if used for IMGUI)."); public readonly GUIContent borderMipMaps = new GUIContent("Border Mip Maps"); -#if ENABLE_TEXTURE_STREAMING +#if ENABLE_TEXTURE_STREAMING public readonly GUIContent streamingMipMaps = EditorGUIUtility.TrTextContent("Mip Streaming", "Only load larger mipmaps as needed to render the current game cameras. Requires texture streaming to be enabled in quality settings."); public readonly GUIContent streamingMipmapsPriority = EditorGUIUtility.TrTextContent("Priority", "Mipmap streaming priority when there's contention for resources. Positive numbers represent higher priority. Valid range is -128 to 127."); -#endif +#endif public readonly GUIContent mipMapsPreserveCoverage = new GUIContent("Mip Maps Preserve Coverage", "The alpha channel of generated Mip Maps will preserve coverage during the alpha test."); public readonly GUIContent alphaTestReferenceValue = new GUIContent("Alpha Cutoff Value", "The reference value used during the alpha test. Controls Mip Map coverage."); public readonly GUIContent mipMapFilter = new GUIContent("Mip Map Filtering"); @@ -1602,7 +1612,7 @@ internal class Styles new GUIContent("Kaiser"), }; public readonly GUIContent npot = new GUIContent("Non Power of 2", "How non-power-of-two textures are scaled on import."); - + public readonly GUIContent spriteMode = new GUIContent("Sprite Mode"); public readonly GUIContent[] spriteModeOptions = { @@ -1615,7 +1625,7 @@ internal class Styles new GUIContent("Full Rect"), new GUIContent("Tight"), }; - + public readonly GUIContent spritePixelsPerUnit = new GUIContent("Pixels Per Unit", "How many pixels in the sprite correspond to one unit in the world."); public readonly GUIContent spriteExtrude = new GUIContent("Extrude Edges", "How much empty area to leave around the sprite in the generated mesh."); public readonly GUIContent spriteMeshType = new GUIContent("Mesh Type", "Type of sprite mesh to generate."); @@ -1647,7 +1657,7 @@ internal class Styles public readonly GUIContent spriteEditorButtonLabel = new GUIContent("Open Sprite Editor"); public readonly GUIContent resliceFromLayerWarning = new GUIContent("This will reinitialize and recreate all Sprites based on the file’s layer data. Existing Sprite metadata from previously generated Sprites are copied over."); public readonly GUIContent alphaIsTransparency = new GUIContent("Alpha Is Transparency", "If the provided alpha channel is transparency, enable this to pre-filter the color to avoid texture filtering artifacts. This is not supported for HDR textures."); - + public readonly GUIContent advancedHeaderText = new GUIContent("Advanced", "Show advanced settings."); public readonly GUIContent platformSettingsHeaderText = new GUIContent("Platform Setttings"); @@ -1676,7 +1686,7 @@ internal class Styles (int)TextureWrapMode.MirrorOnce, -1 }; - + public readonly GUIContent layerMapping = EditorGUIUtility.TrTextContent("Layer Mapping", "Options for indicating how layer to Sprite mapping."); public readonly GUIContent generatePhysicsShape = EditorGUIUtility.TrTextContent("Generate Physics Shape", "Generates a default physics shape from the outline of the Sprite/s when a physics shape has not been set in the Sprite Editor."); public readonly GUIContent importHiddenLayer = EditorGUIUtility.TrTextContent("Include Hidden Layers", "Settings to determine when hidden layers should be imported."); @@ -1698,28 +1708,28 @@ internal class Styles 0, 1 }; - + public readonly GUIContent[] importModeOptions= { EditorGUIUtility.TrTextContent("Individual Sprites (Mosaic)","Import individual Photoshop layers as Sprites."), new GUIContent("Merged","Merge Photoshop layers and import as single Sprite.") }; - - + + public readonly GUIContent[] layerMappingOption= { EditorGUIUtility.TrTextContent("Use Layer ID","Use layer's ID to identify layer and Sprite mapping."), EditorGUIUtility.TrTextContent("Use Layer Name","Use layer's name to identify layer and Sprite mapping."), EditorGUIUtility.TrTextContent("Use Layer Name (Case Sensitive)","Use layer's name to identify layer and Sprite mapping."), }; - + public readonly int[] layerMappingOptionValues = { (int)PSDImporter.ELayerMappingOption.UseLayerId, (int)PSDImporter.ELayerMappingOption.UseLayerName, (int)PSDImporter.ELayerMappingOption.UseLayerNameCaseSensitive }; - + public readonly GUIContent[] layerGroupOption= { EditorGUIUtility.TrTextContent("Ignore Layer Groups","Only layers will generate GameObjects."), @@ -1731,11 +1741,11 @@ internal class Styles EditorGUIUtility.TrTextContent("Settings", "Importer Settings."), EditorGUIUtility.TrTextContent("Layer Management", "Layer merge settings.") }; - + public readonly GUIContent swizzle = EditorGUIUtility.TrTextContent("Swizzle", "Reorder and invert texture color channels. For each of R,G,B,A channels pick where the channel data comes from."); public readonly string[] swizzleOptions = new[] {"R","G","B","A", "1-R","1-G","1-B","1-A", "0","1" }; - + public Styles() { // This is far from ideal, but it's better than having tons of logic in the GUI code itself. @@ -1793,13 +1803,13 @@ public PSDImporterEditorFoldOutState() m_TextureFoldout = new SavedBool("PSDImporterEditor.m_TextureFoldout", false); m_PlatformSettingsFoldout = new SavedBool("PSDImporterEditor.m_PlatformSettingsFoldout", false); } - + bool DoFoldout(GUIContent title, bool state) { InspectorUtils.DrawSplitter(); return InspectorUtils.DrawHeaderFoldout(title, state); } - + public bool DoGeneralUI(GUIContent title) { m_GeneralFoldout.value = DoFoldout(title, m_GeneralFoldout.value); @@ -1829,13 +1839,13 @@ public bool DoPlatformSettingsUI(GUIContent title) m_PlatformSettingsFoldout.value = DoFoldout(title, m_PlatformSettingsFoldout.value); return m_PlatformSettingsFoldout.value; } - + public bool DoTextureUI(GUIContent title) { m_TextureFoldout.value = DoFoldout(title, m_TextureFoldout.value); return m_TextureFoldout.value; } - + class SavedBool { bool m_Value; @@ -1877,4 +1887,4 @@ public static implicit operator bool(SavedBool s) } } } -} +} \ No newline at end of file diff --git a/Editor/Pipeline.asset b/Editor/Pipeline.asset new file mode 100644 index 0000000..9e63ea4 --- /dev/null +++ b/Editor/Pipeline.asset @@ -0,0 +1,14 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 90847c0a31834ab383dcd062f4ec41bd, type: 3} + m_Name: Pipeline + m_EditorClassIdentifier: diff --git a/Editor/Pipeline.asset.meta b/Editor/Pipeline.asset.meta new file mode 100644 index 0000000..25251f3 --- /dev/null +++ b/Editor/Pipeline.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7a602206d712e496b8b4f2c9fb6ce07c +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Pipeline.cs b/Editor/Pipeline.cs new file mode 100644 index 0000000..c7f7091 --- /dev/null +++ b/Editor/Pipeline.cs @@ -0,0 +1,15 @@ +using Unity.Collections; +using UnityEditor.U2D.Common; +using UnityEngine; + +namespace UnityEditor.U2D.PSD +{ + //[CreateAssetMenu(fileName = "Pipeline.asset", menuName = "2D/PSDImporter Pipeline")] + class Pipeline : ScriptableObject + { + void PackImage(NativeArray[] buffers, int[] width, int[] height, int padding, uint spriteSizeExpand, out NativeArray outPackedBuffer, out int outPackedBufferWidth, out int outPackedBufferHeight, out RectInt[] outPackedRect, out Vector2Int[] outUVTransform, bool requireSquarePOT = false) + { + ImagePacker.Pack(buffers, width, height, padding, spriteSizeExpand, out outPackedBuffer, out outPackedBufferWidth, out outPackedBufferHeight, out outPackedRect, out outUVTransform, requireSquarePOT); + } + } +} \ No newline at end of file diff --git a/Editor/Pipeline.cs.meta b/Editor/Pipeline.cs.meta new file mode 100644 index 0000000..507450b --- /dev/null +++ b/Editor/Pipeline.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 90847c0a31834ab383dcd062f4ec41bd +timeCreated: 1699106067 \ No newline at end of file diff --git a/Samples~/PSDImporterSamples/.sample.json b/Samples~/PSDImporterSamples/.sample.json new file mode 100644 index 0000000..bec248a --- /dev/null +++ b/Samples~/PSDImporterSamples/.sample.json @@ -0,0 +1,5 @@ +{ + "displayName": "2D PSDImporter Samples", + "interactiveImport": "true", + "description": "Various examples demonstrating the usage of 2D PSDImporter." +} diff --git a/Samples~/PSDImporterSamples/LICENSE.md b/Samples~/PSDImporterSamples/LICENSE.md new file mode 100644 index 0000000..46b111d --- /dev/null +++ b/Samples~/PSDImporterSamples/LICENSE.md @@ -0,0 +1,5 @@ +com.unity.2d.psdimporter Samples © 2023 Unity Technologies + +Licensed under the Unity Companion License for Unity-dependent projects (see https://unity3d.com/legal/licenses/unity_companion_license). + +Unless expressly provided otherwise, the Software under this license is made available strictly on an “AS IS” BASIS WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. Please review the license for details on these and other terms and conditions. \ No newline at end of file diff --git a/Samples~/PSDImporterSamples/LICENSE.md.meta b/Samples~/PSDImporterSamples/LICENSE.md.meta new file mode 100644 index 0000000..a398591 --- /dev/null +++ b/Samples~/PSDImporterSamples/LICENSE.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: b913af7f120cd4e4cb5485455afc348d +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/PSDImporterSamples/PSDImporterCustomPacker.meta b/Samples~/PSDImporterSamples/PSDImporterCustomPacker.meta new file mode 100644 index 0000000..0aee33a --- /dev/null +++ b/Samples~/PSDImporterSamples/PSDImporterCustomPacker.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f56e08d3303714e19a31605c961892d2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/PSDImporterSamples/PSDImporterCustomPacker/Editor.meta b/Samples~/PSDImporterSamples/PSDImporterCustomPacker/Editor.meta new file mode 100644 index 0000000..1c6740c --- /dev/null +++ b/Samples~/PSDImporterSamples/PSDImporterCustomPacker/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 265de3b9572f8476bbe964e7d124579c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/PSDImporterSamples/PSDImporterCustomPacker/Editor/ImagePacker.meta b/Samples~/PSDImporterSamples/PSDImporterCustomPacker/Editor/ImagePacker.meta new file mode 100644 index 0000000..8894e3e --- /dev/null +++ b/Samples~/PSDImporterSamples/PSDImporterCustomPacker/Editor/ImagePacker.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 967bc1bc5f8444bfc807ffef1fdf5c7c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/PSDImporterSamples/PSDImporterCustomPacker/Editor/ImagePacker/ImagePackNode.cs b/Samples~/PSDImporterSamples/PSDImporterCustomPacker/Editor/ImagePacker/ImagePackNode.cs new file mode 100644 index 0000000..c12bc99 --- /dev/null +++ b/Samples~/PSDImporterSamples/PSDImporterCustomPacker/Editor/ImagePacker/ImagePackNode.cs @@ -0,0 +1,213 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace PSDImporterCustomPacker +{ + internal interface IImagePackNodeVisitor + { + void Visit(ImagePackNode node); + } + + class CollectEmptyNodePositionVisitor : IImagePackNodeVisitor + { + public List emptyAreas = new List(); + public void Visit(ImagePackNode node) + { + if (node.imageId == -1) + { + emptyAreas.Add(node.rect); + } + } + } + + class CollectPackNodePositionVisitor : IImagePackNodeVisitor + { + public CollectPackNodePositionVisitor() + { + positions = new Vector2Int[0]; + } + + public void Visit(ImagePackNode node) + { + if (node.imageId != -1) + { + if (positions.Length < node.imageId + 1) + { + var p = positions; + Array.Resize(ref p, node.imageId + 1); + positions = p; + } + + positions[node.imageId].x = node.rect.x; + positions[node.imageId].y = node.rect.y; + } + } + + public Vector2Int[] positions { get; private set; } + } + + internal class ImagePackNode + { + public ImagePackNode left; + public ImagePackNode right; + public RectInt rect; + public Vector2Int imageWidth; + public int imageId = -1; + + public void AcceptVisitor(IImagePackNodeVisitor visitor) + { + visitor.Visit(this); + if (left != null) + left.AcceptVisitor(visitor); + if (right != null) + right.AcceptVisitor(visitor); + } + + public void AdjustSize(int oriWidth, int oriHeight, int deltaW, int deltaH, out int adjustx, out int adjusty) + { + adjustx = adjusty = 0; + int adjustXleft = 0, adjustYleft = 0, adjustXRight = 0, adjustYRight = 0; + if (imageId == -1 || left == null) + { + if (rect.x + rect.width == oriWidth) + { + rect.width += deltaW; + adjustx = deltaW; + } + if (rect.y + rect.height == oriHeight) + { + rect.height += deltaH; + adjusty = deltaH; + } + } + else + { + left.AdjustSize(oriWidth, oriHeight, deltaW, deltaH, out adjustXleft, out adjustYleft); + right.AdjustSize(oriWidth, oriHeight, deltaW, deltaH, out adjustXRight, out adjustYRight); + + adjustx = Mathf.Max(adjustXleft, adjustXRight); + rect.width += adjustx; + adjusty = Mathf.Max(adjustYleft, adjustYRight); + rect.height += adjusty; + } + } + + public bool TryInsert(ImagePacker.ImagePackRect insert, int padding, out Vector2Int remainingSpace) + { + remainingSpace = Vector2Int.zero; + int insertWidth = insert.rect.width + padding * 2; + int insertHeight = insert.rect.height + padding * 2; + if (insertWidth > rect.width || insertHeight > rect.height) + return false; + + if (imageId == -1) + { + remainingSpace.x = rect.width - insertWidth; + remainingSpace.y = rect.height - insertHeight; + } + else + { + Vector2Int spaceLeft, spaceRight; + bool insertLeft, insertRight; + ImagePackNode tryLeft, tryRight; + tryLeft = left; + tryRight = right; + if (left == null && !SplitRects(this, insert, padding, out tryLeft, out tryRight)) + { + return false; + } + + insertLeft = tryLeft.TryInsert(insert, padding, out spaceLeft); + insertRight = tryRight.TryInsert(insert, padding, out spaceRight); + if (insertLeft && insertRight) + { + remainingSpace = spaceLeft.sqrMagnitude < spaceRight.sqrMagnitude ? spaceLeft : spaceRight; + } + else if (insertLeft) + remainingSpace = spaceLeft; + else if (insertRight) + remainingSpace = spaceRight; + else + return false; + } + + return true; + } + + static bool SplitRects(ImagePackNode node, ImagePacker.ImagePackRect insert, int padding, out ImagePackNode left, out ImagePackNode right) + { + // Find the best way to split the rect based on a new rect + left = right = null; + var tryRects = new[] + { + new ImagePackNode(), new ImagePackNode(), + new ImagePackNode(), new ImagePackNode() + }; + + tryRects[0].rect = new RectInt(node.rect.x + node.imageWidth.x, node.rect.y, node.rect.width - node.imageWidth.x, node.rect.height); + tryRects[1].rect = new RectInt(node.rect.x, node.rect.y + node.imageWidth.y, node.imageWidth.x, node.rect.height - node.imageWidth.y); + tryRects[2].rect = new RectInt(node.rect.x, node.rect.y + node.imageWidth.y, node.rect.width, node.rect.height - node.imageWidth.y); + tryRects[3].rect = new RectInt(node.rect.x + node.imageWidth.x, node.rect.y, node.rect.width - node.imageWidth.x, node.imageWidth.y); + float smallestSpace = float.MinValue; + for (int i = 0; i < tryRects.GetLength(0); ++i) + { + //for (int j = 0; j < tryRects.GetLength(1); ++j) + { + Vector2Int newSpaceLeft; + if (tryRects[i].TryInsert(insert, padding, out newSpaceLeft)) + { + if (smallestSpace < newSpaceLeft.sqrMagnitude) + { + smallestSpace = newSpaceLeft.sqrMagnitude; + int index = i / 2 * 2; + left = tryRects[index]; + right = tryRects[index + 1]; + } + } + } + } + return left != null; + } + + public bool Insert(ImagePacker.ImagePackRect insert, int padding) + { + int insertWidth = insert.rect.width + padding * 2; + int insertHeight = insert.rect.height + padding * 2; + if (insertWidth > rect.width || insertHeight > rect.height) + return false; + + if (imageId == -1) + { + imageId = insert.index; + imageWidth = new Vector2Int(insertWidth, insertHeight); + } + else + { + if (left == null && !SplitRects(this, insert, padding, out left, out right)) + { + return false; + } + // We assign to the node that has a better fit for the image + Vector2Int spaceLeft, spaceRight; + bool insertLeft, insertRight; + insertLeft = left.TryInsert(insert, padding, out spaceLeft); + insertRight = right.TryInsert(insert, padding, out spaceRight); + if (insertLeft && insertRight) + { + if (spaceLeft.sqrMagnitude < spaceRight.sqrMagnitude) + left.Insert(insert, padding); + else + right.Insert(insert, padding); + } + else if (insertLeft) + left.Insert(insert, padding); + else if (insertRight) + right.Insert(insert, padding); + else + return false; + } + return true; + } + } +} \ No newline at end of file diff --git a/Samples~/PSDImporterSamples/PSDImporterCustomPacker/Editor/ImagePacker/ImagePacker.cs b/Samples~/PSDImporterSamples/PSDImporterCustomPacker/Editor/ImagePacker/ImagePacker.cs new file mode 100644 index 0000000..8064769 --- /dev/null +++ b/Samples~/PSDImporterSamples/PSDImporterCustomPacker/Editor/ImagePacker/ImagePacker.cs @@ -0,0 +1,159 @@ +using System; +using UnityEngine; +using Unity.Collections; +using Unity.Collections.LowLevel.Unsafe; + +namespace PSDImporterCustomPacker +{ + internal static class ImagePacker + { + /// + /// Given an array of rects, the method returns an array of rects arranged within outPackedWidth and outPackedHeight + /// + /// Rects to pack + /// Padding between each rect + /// Rects arranged within outPackedWidth and outPackedHeight + /// Width of the packed rects + /// Height of the packed rects + public static void Pack(RectInt[] rects, int padding, out RectInt[] outPackedRects, out int outPackedWidth, out int outPackedHeight) + { + var packNode = InternalPack(rects, padding); + outPackedWidth = packNode.rect.width; + outPackedHeight = packNode.rect.height; + var visitor = new CollectPackNodePositionVisitor(); + packNode.AcceptVisitor(visitor); + + outPackedRects = new RectInt[rects.Length]; + for (int i = 0; i < rects.Length; ++i) + outPackedRects[i] = new RectInt(visitor.positions[i].x + padding, visitor.positions[i].y + padding, rects[i].width, rects[i].height); + } + + /// + /// Packs image buffer into a single buffer. Image buffers are assumed to be 4 bytes per pixel in RGBA format + /// + /// Image buffers to pack + /// Image buffers width + /// Image buffers height + /// Padding between each packed image + /// Packed image buffer + /// Packed image buffer's width + /// Packed iamge buffer's height + /// Location of each image buffers in the packed buffer + /// Translation data from image original buffer to packed buffer + public static void Pack(NativeArray[] buffers, int[] width, int[] height, int padding, out NativeArray outPackedBuffer, out int outPackedBufferWidth, out int outPackedBufferHeight, out RectInt[] outPackedRect, out Vector2Int[] outUVTransform) + { + UnityEngine.Profiling.Profiler.BeginSample("Pack"); + // Determine the area that contains data in the buffer + outPackedBuffer = default(NativeArray); + try + { + var tightRects = FindTightRectJob.Execute(buffers, width, height); + Pack(tightRects, padding, out outPackedRect, out outPackedBufferWidth, out outPackedBufferHeight); + outUVTransform = new Vector2Int[tightRects.Length]; + for (int i = 0; i < outUVTransform.Length; ++i) + { + outUVTransform[i] = new Vector2Int(outPackedRect[i].x - tightRects[i].x, outPackedRect[i].y - tightRects[i].y); + } + outPackedBuffer = new NativeArray(outPackedBufferWidth * outPackedBufferHeight, Allocator.Persistent); + + Blit(outPackedBuffer, outPackedRect, outPackedBufferWidth, buffers, tightRects, width, padding); + } + catch (Exception ex) + { + if (outPackedBuffer.IsCreated) + outPackedBuffer.Dispose(); + throw ex; + } + finally + { + UnityEngine.Profiling.Profiler.EndSample(); + } + } + + static ImagePackNode InternalPack(RectInt[] rects, int padding) + { + if (rects == null || rects.Length == 0) + return new ImagePackNode() { rect = new RectInt(0, 0, 0, 0)}; + var sortedRects = new ImagePackRect[rects.Length]; + for (int i = 0; i < rects.Length; ++i) + { + sortedRects[i] = new ImagePackRect(); + sortedRects[i].rect = rects[i]; + sortedRects[i].index = i; + } + Array.Sort(sortedRects); + var root = new ImagePackNode(); + root.rect = new RectInt(0, 0, (int)NextPowerOfTwo((ulong)rects[0].width), (int)NextPowerOfTwo((ulong)rects[0].height)); + + for (int i = 0; i < rects.Length; ++i) + { + if (!root.Insert(sortedRects[i], padding)) // we can't fit + { + int newWidth = root.rect.width , newHeight = root.rect.height; + if (root.rect.width < root.rect.height) + newWidth = (int)NextPowerOfTwo((ulong)root.rect.width + 1); + else + newHeight = (int)NextPowerOfTwo((ulong)root.rect.height + 1); + // Reset all packing and try again + root = new ImagePackNode(); + root.rect = new RectInt(0, 0, newWidth, newHeight); + i = -1; + } + } + return root; + } + + public static unsafe void Blit(NativeArray buffer, RectInt[] blitToArea, int bufferbytesPerRow, NativeArray[] originalBuffer, RectInt[] blitFromArea, int[] bytesPerRow, int padding) + { + UnityEngine.Profiling.Profiler.BeginSample("Blit"); + + var c = (Color32*)buffer.GetUnsafePtr(); + for (int bufferIndex = 0; bufferIndex < blitToArea.Length && bufferIndex < originalBuffer.Length && bufferIndex < blitFromArea.Length; ++bufferIndex) + { + var b = (Color32*)originalBuffer[bufferIndex].GetUnsafeReadOnlyPtr(); + var rectFrom = blitFromArea[bufferIndex]; + var rectTo = blitToArea[bufferIndex]; + for (int i = 0; i < rectFrom.height; ++i) + { + for (int j = 0; j < rectFrom.width; ++j) + { + Color32 cc = b[(rectFrom.y + i) * bytesPerRow[bufferIndex] + rectFrom.x + j]; + c[((rectTo.y + i) * bufferbytesPerRow) + rectTo.x + j] = cc; + } + } + } + UnityEngine.Profiling.Profiler.EndSample(); + } + + internal static ulong NextPowerOfTwo(ulong v) + { + v -= 1; + v |= v >> 16; + v |= v >> 8; + v |= v >> 4; + v |= v >> 2; + v |= v >> 1; + return v + 1; + } + + internal class ImagePackRect : IComparable + { + public RectInt rect; + public int index; + + public int CompareTo(ImagePackRect obj) + { + var lhsArea = rect.width * rect.height; + var rhsArea = obj.rect.width * obj.rect.height; + if (lhsArea > rhsArea) + return -1; + if (lhsArea < rhsArea) + return 1; + if (index < obj.index) + return -1; + + return 1; + } + } + } +} \ No newline at end of file diff --git a/Samples~/PSDImporterSamples/PSDImporterCustomPacker/Editor/ImagePacker/ImagePacker.cs.meta b/Samples~/PSDImporterSamples/PSDImporterCustomPacker/Editor/ImagePacker/ImagePacker.cs.meta new file mode 100644 index 0000000..d331c06 --- /dev/null +++ b/Samples~/PSDImporterSamples/PSDImporterCustomPacker/Editor/ImagePacker/ImagePacker.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8e7d441c9e1074052be514daa51da00b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/PSDImporterSamples/PSDImporterCustomPacker/Editor/ImagePacker/Jobs.meta b/Samples~/PSDImporterSamples/PSDImporterCustomPacker/Editor/ImagePacker/Jobs.meta new file mode 100644 index 0000000..f02203c --- /dev/null +++ b/Samples~/PSDImporterSamples/PSDImporterCustomPacker/Editor/ImagePacker/Jobs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2c2c27855a1af4eb6ab84d3d68746f6b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/PSDImporterSamples/PSDImporterCustomPacker/Editor/PSDImporterCustomPacker.asmdef b/Samples~/PSDImporterSamples/PSDImporterCustomPacker/Editor/PSDImporterCustomPacker.asmdef new file mode 100644 index 0000000..f5a925e --- /dev/null +++ b/Samples~/PSDImporterSamples/PSDImporterCustomPacker/Editor/PSDImporterCustomPacker.asmdef @@ -0,0 +1,16 @@ +{ + "name": "PSDImporterCustomPacker", + "rootNamespace": "", + "references": [], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": true, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Samples~/PSDImporterSamples/PSDImporterCustomPacker/Editor/Pipeline.asset b/Samples~/PSDImporterSamples/PSDImporterCustomPacker/Editor/Pipeline.asset new file mode 100644 index 0000000..f0a8731 --- /dev/null +++ b/Samples~/PSDImporterSamples/PSDImporterCustomPacker/Editor/Pipeline.asset @@ -0,0 +1,16 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a6685f0db9a6426babc498e5330c2260, type: 3} + m_Name: Pipeline + m_EditorClassIdentifier: + m_ObjectsToApply: [] + m_ObjectsAppliedPreviously: [] diff --git a/Samples~/PSDImporterSamples/PSDImporterCustomPacker/Editor/Pipeline.asset.meta b/Samples~/PSDImporterSamples/PSDImporterCustomPacker/Editor/Pipeline.asset.meta new file mode 100644 index 0000000..12089e3 --- /dev/null +++ b/Samples~/PSDImporterSamples/PSDImporterCustomPacker/Editor/Pipeline.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e7ab7c5b6814049a1b493d82b6e14031 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/PSDImporterSamples/PSDImporterCustomPacker/README.md b/Samples~/PSDImporterSamples/PSDImporterCustomPacker/README.md new file mode 100644 index 0000000..e3a5680 --- /dev/null +++ b/Samples~/PSDImporterSamples/PSDImporterCustomPacker/README.md @@ -0,0 +1,9 @@ +# PSDImporter Custom Image Packer + +This example shows how to override the default image packing algorithm in the PSDImporter. + +The example utilizes the `m_Pipeline` SerializedProperty that is defined in the PSDImporter. + +The `m_Pipeline` is a ScriptableObject reference and in the PSDImporter it will determine what method is available in the SciptableObject and execute those methods accordingly. + +Refer to the `CustomPackScriptableObject.cs` for more details. \ No newline at end of file diff --git a/Samples~/PSDImporterSamples/PSDImporterCustomPacker/README.md.meta b/Samples~/PSDImporterSamples/PSDImporterCustomPacker/README.md.meta new file mode 100644 index 0000000..5f3ab01 --- /dev/null +++ b/Samples~/PSDImporterSamples/PSDImporterCustomPacker/README.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: f6afec105e3164ef28f858d824eb786a +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/PSDImporterSamples/README.md b/Samples~/PSDImporterSamples/README.md new file mode 100644 index 0000000..805c62c --- /dev/null +++ b/Samples~/PSDImporterSamples/README.md @@ -0,0 +1,2 @@ +# 2D PSDImporter Samples +2D PSDImporter samples showing various use cases. diff --git a/Samples~/PSDImporterSamples/README.md.meta b/Samples~/PSDImporterSamples/README.md.meta new file mode 100644 index 0000000..50ef435 --- /dev/null +++ b/Samples~/PSDImporterSamples/README.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c0b4d008961224d04ac8c041baf4a9b2 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/package.json b/package.json index 2a8d83c..282de89 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "com.unity.2d.psdimporter", - "version": "9.0.1", + "version": "9.0.2", "unity": "2023.1", "displayName": "2D PSD Importer", "description": "A ScriptedImporter for importing Adobe Photoshop PSB (Photoshop Big) file format. The ScriptedImporter is currently targeted for users who wants to create multi Sprite character animation using Unity 2D Animation Package.", @@ -11,22 +11,29 @@ ], "category": "2D", "dependencies": { - "com.unity.2d.common": "9.0.2", + "com.unity.2d.common": "9.0.4", "com.unity.2d.sprite": "1.0.0" }, "relatedPackages": { - "com.unity.2d.psdimporter.tests": "9.0.1" + "com.unity.2d.psdimporter.tests": "9.0.2" }, + "samples": [ + { + "displayName": "Samples", + "description": "Samples for using PSDImporter.", + "path": "Samples~/PSDImporterSamples" + } + ], "_upm": { - "changelog": "### Fixed\n- Fixed case where PSDImporter does not support the PVRTC compression format for the iOS platform. (Case DANB-500)" + "changelog": "### Fixed\n- Provide custom packing override for users to override to address DANB-526. (Case DANB-526)\n- Fixed layers are not shown in LayerImportSettings after unselecting all layers and applying. (Case DANB-569)" }, "upmCi": { - "footprint": "a0d6f3e508ae71cd512a92da6ea47a0df9be61eb" + "footprint": "d8630d2026a2a1f0ccffccd1458e4ec610fda110" }, "documentationUrl": "https://docs.unity3d.com/Packages/com.unity.2d.psdimporter@9.0/manual/index.html", "repository": { "url": "https://github.cds.internal.unity3d.com/unity/2d.git", "type": "git", - "revision": "b0f3a8f8d95618bb6a299742c1bbd4e96699180b" + "revision": "de1d2b0a924b0621324b0cfe0fcbef92f03bd2c2" } }