1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675 |
- using System;
- using System.Collections.Generic;
- using System.IO;
- using PDNWrapper;
- using UnityEngine;
- using Unity.Collections;
- using System.Linq;
- using UnityEditor.AssetImporters;
- using UnityEditor.U2D.Animation;
- using UnityEditor.U2D.Common;
- using UnityEditor.U2D.Sprites;
- using UnityEngine.Assertions;
- using UnityEngine.U2D;
- using UnityEngine.U2D.Animation;
- using UnityEngine.Scripting.APIUpdating;
-
- namespace UnityEditor.U2D.PSD
- {
- /// <summary>
- /// ScriptedImporter to import Photoshop files
- /// </summary>
- // Version using unity release + 5 digit padding for future upgrade. Eg 2021.2 -> 21200000
- [ScriptedImporter(21200003, "psb", AllowCaching = true)]
- [HelpURL("https://docs.unity3d.com/Packages/com.unity.2d.psdimporter@latest")]
- [MovedFrom("UnityEditor.Experimental.AssetImporters")]
- public class PSDImporter : ScriptedImporter, ISpriteEditorDataProvider
- {
- internal enum ELayerMappingOption
- {
- UseLayerName,
- UseLayerNameCaseSensitive,
- UseLayerId
- }
-
- IPSDLayerMappingStrategy[] m_MappingCompare =
- {
- new LayerMappingUseLayerName(),
- new LayerMappingUseLayerNameCaseSensitive(),
- new LayerMappingUserLayerID(),
- };
-
- [SerializeField]
- TextureImporterSettings m_TextureImporterSettings = new TextureImporterSettings()
- {
- mipmapEnabled = true,
- mipmapFilter = TextureImporterMipFilter.BoxFilter,
- sRGBTexture = true,
- borderMipmap = false,
- mipMapsPreserveCoverage = false,
- alphaTestReferenceValue = 0.5f,
- readable = false,
-
- #if ENABLE_TEXTURE_STREAMING
- streamingMipmaps = true,
- #endif
-
- fadeOut = false,
- mipmapFadeDistanceStart = 1,
- mipmapFadeDistanceEnd = 3,
-
- convertToNormalMap = false,
- heightmapScale = 0.25F,
- normalMapFilter = 0,
-
- generateCubemap = TextureImporterGenerateCubemap.AutoCubemap,
- cubemapConvolution = 0,
-
- seamlessCubemap = false,
-
- npotScale = TextureImporterNPOTScale.ToNearest,
-
- spriteMode = (int)SpriteImportMode.Multiple,
- spriteExtrude = 1,
- spriteMeshType = SpriteMeshType.Tight,
- spriteAlignment = (int)SpriteAlignment.Center,
- spritePivot = new Vector2(0.5f, 0.5f),
- spritePixelsPerUnit = 100.0f,
- spriteBorder = new Vector4(0.0f, 0.0f, 0.0f, 0.0f),
-
- alphaSource = TextureImporterAlphaSource.FromInput,
- alphaIsTransparency = true,
- spriteTessellationDetail = -1.0f,
-
- textureType = TextureImporterType.Sprite,
- textureShape = TextureImporterShape.Texture2D,
-
- filterMode = FilterMode.Bilinear,
- aniso = 1,
- mipmapBias = 0.0f,
- wrapModeU = TextureWrapMode.Repeat,
- wrapModeV = TextureWrapMode.Repeat,
- wrapModeW = TextureWrapMode.Repeat,
- };
-
- [SerializeField]
- // SpriteData for both single and multiple mode
- List<SpriteMetaData> m_SpriteImportData = new List<SpriteMetaData>(); // we use index 0 for single sprite and the rest for multiple sprites
- [SerializeField]
- // SpriteData for Mosaic mode
- List<SpriteMetaData> m_MosaicSpriteImportData = new List<SpriteMetaData>();
- [SerializeField]
- // SpriteData for Rig mode
- List<SpriteMetaData> m_RigSpriteImportData = new List<SpriteMetaData>();
- [SerializeField]
- // CharacterData for Rig mode
- CharacterData m_CharacterData = new CharacterData();
- [SerializeField]
- // SpriteData for shared rig mode
- List<SpriteMetaData> m_SharedRigSpriteImportData = new List<SpriteMetaData>();
- [SerializeField]
- // CharacterData for shared rig mode
- CharacterData m_SharedRigCharacterData = new CharacterData();
-
- [SerializeField]
- List<TextureImporterPlatformSettings> m_PlatformSettings = new List<TextureImporterPlatformSettings>();
- [SerializeField]
- bool m_MosaicLayers = true;
- [SerializeField]
- bool m_CharacterMode = true;
- [SerializeField]
- Vector2 m_DocumentPivot = Vector2.zero;
- [SerializeField]
- SpriteAlignment m_DocumentAlignment = SpriteAlignment.BottomCenter;
- [SerializeField]
- bool m_ImportHiddenLayers = false;
- [SerializeField]
- ELayerMappingOption m_LayerMappingOption = ELayerMappingOption.UseLayerId;
- [SerializeField]
- bool m_GeneratePhysicsShape = false;
-
- [SerializeField]
- bool m_PaperDollMode = false;
-
- [SerializeField]
- bool m_KeepDupilcateSpriteName = true;
-
- [SerializeField]
- private string m_SkeletonAssetReferenceID = null;
-
- [SerializeField]
- SpriteCategoryList m_SpriteCategoryList = new SpriteCategoryList() {categories = new List<SpriteCategory>()};
- GameObjectCreationFactory m_GameObjectFactory = new GameObjectCreationFactory();
-
- internal SpriteCategoryList spriteCategoryList { get { return m_SpriteCategoryList; } set { m_SpriteCategoryList = value; } }
- PSDImportData m_ImportData;
- internal PSDImportData importData
- {
- get
- {
- var returnValue = m_ImportData;
- if (returnValue == null)
- returnValue = AssetDatabase.LoadAllAssetsAtPath(assetPath).FirstOrDefault(x => x is PSDImportData) as PSDImportData;
-
- if (returnValue == null)
- returnValue = ScriptableObject.CreateInstance<PSDImportData>();
-
- m_ImportData = returnValue;
- return returnValue;
- }
- }
-
- internal int textureActualWidth
- {
- get => importData.textureActualWidth;
- private set =>importData.textureActualWidth = value;
- }
-
- internal int textureActualHeight
- {
- get => importData.textureActualHeight;
- private set =>importData.textureActualHeight = value;
- }
-
- [SerializeField]
- string m_SpritePackingTag = "";
-
- [SerializeField]
- bool m_ResliceFromLayer = false;
-
- [SerializeField]
- List<PSDLayer> m_MosaicPSDLayers = new List<PSDLayer>();
- [SerializeField]
- List<PSDLayer> m_RigPSDLayers = new List<PSDLayer>();
- [SerializeField]
- List<PSDLayer> m_SharedRigPSDLayers = new List<PSDLayer>();
- [SerializeField]
- PSDLayerImportSetting[] m_PSDLayerImportSetting;
-
- [SerializeField]
- bool m_GenerateGOHierarchy = false;
-
- [SerializeField]
- string m_TextureAssetName = null;
-
- [SerializeField]
- string m_PrefabAssetName = null;
-
- [SerializeField]
- string m_SpriteLibAssetName = null;
-
- [SerializeField]
- string m_SkeletonAssetName = null;
-
- [SerializeField]
- SecondarySpriteTexture[] m_SecondarySpriteTextures;
-
- PSDExtractLayerData[] m_ExtractData;
-
- /// <summary>
- /// Implementation of ScriptedImporter.OnImportAsset
- /// </summary>
- /// <param name="ctx">
- /// This argument contains all the contextual information needed to process the import
- /// event and is also used by the custom importer to store the resulting Unity Asset.
- /// </param>
- 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<PSDImportData>();
- m_ImportData.hideFlags = HideFlags.HideInHierarchy;
-
- try
- {
- UnityEngine.Profiling.Profiler.BeginSample("OnImportAsset");
-
- UnityEngine.Profiling.Profiler.BeginSample("PsdLoad");
- doc = PaintDotNet.Data.PhotoshopFileType.PsdLoad.Load(fileStream);
- UnityEngine.Profiling.Profiler.EndSample();
-
- m_ImportData.CreatePSDLayerData(doc.Layers);
-
- ValidatePSDLayerId(doc);
- SetDocumentImportData(doc);
-
- importData.documentSize = new Vector2Int(doc.width, doc.height);
- var singleSpriteMode = m_TextureImporterSettings.textureType == TextureImporterType.Sprite && m_TextureImporterSettings.spriteMode != (int)SpriteImportMode.Multiple;
- EnsureSingleSpriteExist();
-
- if (m_TextureImporterSettings.textureType != TextureImporterType.Sprite ||
- m_MosaicLayers == false || singleSpriteMode)
- {
- var outputImageBuffer = new NativeArray<Color32>(doc.width * doc.height, Allocator.Persistent);
- try
- {
- var spriteImportData = GetSpriteImportData();
- FlattenImageTask.Execute(m_ExtractData, ref outputImageBuffer, m_ImportHiddenLayers, canvasSize);
-
- if (spriteImportData.Count <= 0 || spriteImportData[0] == null)
- {
- spriteImportData.Add(new SpriteMetaData());
- }
-
- spriteImportData[0].name = System.IO.Path.GetFileNameWithoutExtension(ctx.assetPath) + "_1";
- spriteImportData[0].alignment = (SpriteAlignment)m_TextureImporterSettings.spriteAlignment;
- spriteImportData[0].border = m_TextureImporterSettings.spriteBorder;
- spriteImportData[0].pivot = m_TextureImporterSettings.spritePivot;
- spriteImportData[0].rect = new Rect(0, 0, doc.width, doc.height);
- importData.importedTextureWidth = textureActualWidth = doc.width;
- importData.importedTextureHeight = textureActualHeight = doc.height;
- var spriteRects = new SpriteMetaData[0];
- if (m_TextureImporterSettings.textureType == TextureImporterType.Sprite)
- {
- if (singleSpriteMode)
- spriteRects = new[] { spriteImportData[0] };
- else if (spriteImportData.Count > 1)
- spriteRects = spriteImportData.GetRange(1, spriteDataCount).ToArray();
- }
-
- var output = ImportTexture(ctx, outputImageBuffer, doc.width, doc.height, spriteRects);
- importData.importedTextureWidth = output.texture.width;
- importData.importedTextureHeight = output.texture.height;
-
- RegisterAssets(ctx, output);
- }
- finally
- {
- outputImageBuffer.Dispose();
- }
- }
- else
- {
- ImportFromLayers(ctx);
- }
-
- if (!string.IsNullOrEmpty(m_SkeletonAssetReferenceID))
- {
- var primaryAssetPath = AssetDatabase.GUIDToAssetPath(m_SkeletonAssetReferenceID);
- if(!string.IsNullOrEmpty(primaryAssetPath) && primaryAssetPath != assetPath)
- {
- ctx.DependsOnArtifact(primaryAssetPath);
- }
- }
- ctx.AddObjectToAsset("PSDImportData", m_ImportData);
- }
- finally
- {
- fileStream.Close();
- if (doc != null)
- doc.Dispose();
- UnityEngine.Profiling.Profiler.EndSample();
- EditorUtility.SetDirty(this);
- }
-
- }
-
- static void ValidatePSDLayerId(IEnumerable<PSDLayer> oldPsdLayer, IEnumerable<BitmapLayer> layers, UniqueNameGenerator uniqueNameGenerator)
- {
- // first check if all layers are unique. If not, we use back the previous layer id based on name match
- HashSet<int> uniqueIdSet = new HashSet<int>();
- bool useOldID = false;
- foreach(var layer in layers)
- {
- if (uniqueIdSet.Contains(layer.LayerID))
- {
- useOldID = true;
- break;
- }
- uniqueIdSet.Add(layer.LayerID);
- }
-
- for (int i = 0; i < layers.Count(); ++i)
- {
- var childBitmapLayer = layers.ElementAt(i);
- // fix case 1291323
- if (useOldID)
- {
- var oldLayers = oldPsdLayer.Where(x => x.name == childBitmapLayer.Name);
- if (oldLayers.Count() == 0)
- oldLayers = oldPsdLayer.Where(x => x.layerID == childBitmapLayer.Name.GetHashCode());
- // pick one that is not already on the list
- foreach (var ol in oldLayers)
- {
- if (!uniqueNameGenerator.ContainHash(ol.layerID))
- {
- childBitmapLayer.LayerID = ol.layerID;
- break;
- }
- }
- }
-
- if (uniqueNameGenerator.ContainHash(childBitmapLayer.LayerID))
- {
- var importWarning = string.Format("Layer {0}: LayerId is not unique. Mapping will be done by Layer's name.", childBitmapLayer.Name);
- var layerName = uniqueNameGenerator.GetUniqueName(childBitmapLayer.Name);
- if (layerName != childBitmapLayer.Name)
- importWarning += "\nLayer names are not unique. Please ensure they are unique to for SpriteRect to be mapped back correctly.";
- childBitmapLayer.LayerID = layerName.GetHashCode();
- Debug.LogWarning(importWarning);
- }
- else
- uniqueNameGenerator.AddHash(childBitmapLayer.LayerID);
- if (childBitmapLayer.ChildLayer != null)
- {
- ValidatePSDLayerId(oldPsdLayer, childBitmapLayer.ChildLayer, uniqueNameGenerator);
- }
- }
- }
-
-
- void ValidatePSDLayerId(Document doc)
- {
- if (m_LayerMappingOption == ELayerMappingOption.UseLayerId)
- {
- UniqueNameGenerator uniqueNameGenerator = new UniqueNameGenerator();
- ValidatePSDLayerId(GetPSDLayers(), doc.Layers, uniqueNameGenerator);
- }
- }
-
- TextureGenerationOutput ImportTexture(AssetImportContext ctx, NativeArray<Color32> imageData, int textureWidth, int textureHeight, SpriteMetaData[] sprites)
- {
- if (!imageData.IsCreated || imageData.Length == 0)
- return new TextureGenerationOutput();
-
- UnityEngine.Profiling.Profiler.BeginSample("ImportTexture");
- var platformSettings = GetPlatformTextureSettings(ctx.selectedBuildTarget);
-
- var textureSettings = m_TextureImporterSettings.ExtractTextureSettings();
- textureSettings.assetPath = ctx.assetPath;
- textureSettings.enablePostProcessor = true;
- textureSettings.containsAlpha = true;
- textureSettings.hdr = false;
-
- var textureAlphaSettings = m_TextureImporterSettings.ExtractTextureAlphaSettings();
- var textureMipmapSettings = m_TextureImporterSettings.ExtractTextureMipmapSettings();
- var textureCubemapSettings = m_TextureImporterSettings.ExtractTextureCubemapSettings();
- var textureWrapSettings = m_TextureImporterSettings.ExtractTextureWrapSettings();
-
- TextureGenerationOutput output;
- switch (m_TextureImporterSettings.textureType)
- {
- case TextureImporterType.Default:
- output = TextureGeneratorHelper.GenerateTextureDefault(imageData, textureWidth, textureHeight, textureSettings, platformSettings, textureAlphaSettings, textureMipmapSettings, textureCubemapSettings, textureWrapSettings);
- break;
- case TextureImporterType.NormalMap:
- var textureNormalSettings = m_TextureImporterSettings.ExtractTextureNormalSettings();
- output = TextureGeneratorHelper.GenerateNormalMap(imageData, textureWidth, textureHeight, textureSettings, platformSettings, textureNormalSettings, textureMipmapSettings, textureCubemapSettings, textureWrapSettings);
- break;
- case TextureImporterType.GUI:
- output = TextureGeneratorHelper.GenerateTextureGUI(imageData, textureWidth, textureHeight, textureSettings, platformSettings, textureAlphaSettings, textureMipmapSettings, textureWrapSettings);
- break;
- case TextureImporterType.Sprite:
- var textureSpriteSettings = m_TextureImporterSettings.ExtractTextureSpriteSettings();
- textureSpriteSettings.packingTag = m_SpritePackingTag;
- textureSpriteSettings.qualifyForPacking = !string.IsNullOrEmpty(m_SpritePackingTag);
- textureSpriteSettings.spriteSheetData = new SpriteImportData[sprites.Length];
- textureSettings.npotScale = TextureImporterNPOTScale.None;
- textureSettings.secondaryTextures = secondaryTextures;
-
- for (int i = 0; i < sprites.Length; ++i)
- textureSpriteSettings.spriteSheetData[i] = sprites[i];
-
- output = TextureGeneratorHelper.GenerateTextureSprite(imageData, textureWidth, textureHeight, textureSettings, platformSettings, textureSpriteSettings, textureAlphaSettings, textureMipmapSettings, textureWrapSettings);
- break;
- case TextureImporterType.Cursor:
- output = TextureGeneratorHelper.GenerateTextureCursor(imageData, textureWidth, textureHeight, textureSettings, platformSettings, textureAlphaSettings, textureMipmapSettings, textureWrapSettings);
- break;
- case TextureImporterType.Cookie:
- output = TextureGeneratorHelper.GenerateCookie(imageData, textureWidth, textureHeight, textureSettings, platformSettings, textureAlphaSettings, textureMipmapSettings, textureCubemapSettings, textureWrapSettings);
- break;
- case TextureImporterType.Lightmap:
- output = TextureGeneratorHelper.GenerateLightmap(imageData, textureWidth, textureHeight, textureSettings, platformSettings, textureMipmapSettings, textureWrapSettings);
- break;
- case TextureImporterType.SingleChannel:
- output = TextureGeneratorHelper.GenerateTextureSingleChannel(imageData, textureWidth, textureHeight, textureSettings, platformSettings, textureAlphaSettings, textureMipmapSettings, textureCubemapSettings, textureWrapSettings);
- break;
- default:
- Debug.LogAssertion("Unknown texture type for import");
- output = default(TextureGenerationOutput);
- break;
- }
- UnityEngine.Profiling.Profiler.EndSample();
- return output;
- }
-
- string GetUniqueSpriteName(string name, UniqueNameGenerator generator)
- {
- if (m_KeepDupilcateSpriteName)
- return name;
- return generator.GetUniqueName(name);
- }
-
- void SetDocumentImportData(IEnumerable<BitmapLayer> layers, PSDExtractLayerData[] extractData, IPSDLayerMappingStrategy mappingStrategy, List<PSDLayer> psdLayers, PSDExtractLayerData parent = null)
- {
- for (int i = 0; i < layers.Count(); ++i)
- {
- var layer = layers.ElementAt(i);
- PSDLayerImportSetting importSetting = null;
- if (m_PSDLayerImportSetting != null && m_PSDLayerImportSetting.Length > 0)
- {
- importSetting = m_PSDLayerImportSetting.FirstOrDefault(x => mappingStrategy.Compare(x, layer));
- }
- var c = psdLayers?.FirstOrDefault(x => mappingStrategy.Compare(x, layer));
- if (c != null)
- {
- if(c.spriteID.Empty())
- c.spriteID = importSetting != null ? importSetting.spriteId : GUID.Generate();
- if (importSetting == null)
- {
- importSetting = new PSDLayerImportSetting()
- {
- flatten = c.flatten,
- };
- }
-
- importSetting.spriteId = c.spriteID;
- }
-
- if (importSetting == null)
- {
- importSetting = new PSDLayerImportSetting()
- {
- flatten = false
- };
- }
-
- extractData[i] = new PSDExtractLayerData()
- {
- bitmapLayer = layer,
- importSetting = importSetting,
- };
-
- PSDExtractLayerData[] childrenextractData = null;
- if (layer.ChildLayer != null)
- {
- childrenextractData = new PSDExtractLayerData[layer.ChildLayer.Count()];
- SetDocumentImportData(layer.ChildLayer, childrenextractData, mappingStrategy, psdLayers, extractData[i]);
- }
-
- extractData[i].children = childrenextractData;
- }
- }
-
- void SetDocumentImportData(Document doc)
- {
- var oldPsdLayers = GetPSDLayers();
- var mappingStrategy = GetLayerMappingStrategy();
- m_ExtractData = new PSDExtractLayerData[doc.Layers.Count];
- SetDocumentImportData(doc.Layers, m_ExtractData, mappingStrategy, oldPsdLayers);
- }
-
- void ImportFromLayers(AssetImportContext ctx)
- {
- var output = default(NativeArray<Color32>);
-
- var layerIndex = new List<int>();
- var spriteNameHash = new UniqueNameGenerator();
-
- var oldPsdLayers = GetPSDLayers();
- List<PSDLayer> psdLayers = null;
- 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))
- {
- Debug.LogWarning(layerUnique,this);
- }
- var removedLayersSprite = oldPsdLayers.Where(x => psdLayers.FirstOrDefault(y => mappingStrategy.Compare(y, x)) == null).Select(z => z.spriteID).ToArray();
- bool hasNewLayer = false;
- for (int i = 0; i < psdLayers.Count; ++i)
- {
- int j = 0;
- var psdLayer = psdLayers[i];
- for (; j < oldPsdLayers.Count; ++j)
- {
- if (mappingStrategy.Compare(psdLayer, oldPsdLayers[j]))
- {
- if(oldPsdLayers[j].spriteID.Empty())
- oldPsdLayers[j].spriteID = GUID.Generate();
- psdLayer.spriteID = oldPsdLayers[j].spriteID;
- psdLayer.spriteName = oldPsdLayers[j].spriteName;
- psdLayer.mosaicPosition = oldPsdLayers[j].mosaicPosition;
- if (psdLayer.isImported != oldPsdLayers[j].isImported)
- hasNewLayer = true;
- break;
- }
- }
-
- if(j >= oldPsdLayers.Count)
- hasNewLayer = true;
- }
-
- var layerBuffers = new List<NativeArray<Color32>>();
- var layerWidth = new List<int>();
- var layerHeight = new List<int>();
- for (var i = 0; i < psdLayers.Count; ++i)
- {
- var l = psdLayers[i];
- var expectedBufferLength = l.width * l.height;
- if (l.texture.IsCreated && l.texture.Length == expectedBufferLength && l.isImported)
- {
- layerBuffers.Add(l.texture);
- layerIndex.Add(i);
- layerWidth.Add(l.width);
- layerHeight.Add(l.height);
- }
- }
-
- const int padding = 4;
- ImagePacker.Pack(layerBuffers.ToArray(), layerWidth.ToArray(), layerHeight.ToArray(), padding, out output, out int width, out int height, out RectInt[] spriteData, out Vector2Int[] uvTransform);
-
- 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);
-
- var spriteImportData = GetSpriteImportData();
- if (spriteImportData.Count <= 0 || shouldResliceFromLayer || hasNewLayer)
- {
- var newSpriteMeta = new List<SpriteMetaData>();
-
- for (int i = 0; i < spriteData.Length && i < layerIndex.Count; ++i)
- {
- var psdLayer = psdLayers[layerIndex[i]];
- var spriteSheet = spriteImportData.FirstOrDefault(x => x.spriteID == psdLayer.spriteID);
- if (spriteSheet == null)
- {
- spriteSheet = new SpriteMetaData();
- spriteSheet.border = Vector4.zero;
- spriteSheet.alignment = (SpriteAlignment)m_TextureImporterSettings.spriteAlignment;
- spriteSheet.pivot = m_TextureImporterSettings.spritePivot;
- spriteSheet.rect = new Rect(spriteData[i].x, spriteData[i].y, spriteData[i].width, spriteData[i].height);
- spriteSheet.spriteID = psdLayer.spriteID;
- }
- else
- {
- var r = spriteSheet.rect;
- r.position = r.position - psdLayer.mosaicPosition + spriteData[i].position;
- spriteSheet.rect = r;
- }
-
- psdLayer.spriteName = GetUniqueSpriteName(psdLayer.name, spriteNameHash);
- 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;
- psdLayer.mosaicPosition = spriteData[i].position;
- newSpriteMeta.Add(spriteSheet);
- }
- spriteImportData.Clear();
- spriteImportData.AddRange(newSpriteMeta);
- }
- else
- {
- spriteImportData.RemoveAll(x => removedLayersSprite.Contains(x.spriteID));
-
- // First look for any user created SpriteRect and add those into the name hash
- foreach (var importData in spriteImportData)
- {
- var psdLayer = psdLayers.FirstOrDefault(x => x.spriteID == importData.spriteID);
- if (psdLayer == null)
- spriteNameHash.AddHash(importData.name);
- }
-
- foreach (var importData in spriteImportData)
- {
- var psdLayer = psdLayers.FirstOrDefault(x => x.spriteID == importData.spriteID);
- if (psdLayer == null)
- importData.uvTransform = new Vector2Int((int)importData.rect.position.x, (int)importData.rect.position.y);
- // If it is user created rect or the name has been changed before
- // add it into the spriteNameHash and we don't copy it over from the layer
- if (psdLayer == null || psdLayer.spriteName != importData.name)
- spriteNameHash.AddHash(importData.name);
-
- // If the sprite name has not been changed, we ensure the new
- // layer name is still unique and use it as the sprite name
- if (psdLayer != null && psdLayer.spriteName == importData.name)
- {
- psdLayer.spriteName = GetUniqueSpriteName(psdLayer.name, spriteNameHash);
- importData.name = psdLayer.spriteName;
- }
- }
-
- //Update names for those user has not changed and add new sprite rect based on PSD file.
- for (int k = 0; k < layerIndex.Count; ++k)
- {
- int i = layerIndex[k];
- var spriteSheet = spriteImportData.FirstOrDefault(x => x.spriteID == psdLayers[i].spriteID);
- var inOldLayer = oldPsdLayers.FindIndex(x => mappingStrategy.Compare(x,psdLayers[i])) != -1;
- if (spriteSheet == null && !inOldLayer)
- {
- spriteSheet = new SpriteMetaData();
- spriteImportData.Add(spriteSheet);
- spriteSheet.rect = new Rect(spriteData[k].x, spriteData[k].y, spriteData[k].width, spriteData[k].height);
- spriteSheet.border = Vector4.zero;
- spriteSheet.alignment = (SpriteAlignment)m_TextureImporterSettings.spriteAlignment;
- spriteSheet.pivot = m_TextureImporterSettings.spritePivot;
- spriteSheet.spritePosition = psdLayers[i].layerPosition;
- psdLayers[i].spriteName = GetUniqueSpriteName(psdLayers[i].name, spriteNameHash);
- spriteSheet.name = psdLayers[i].spriteName;
- }
- else if (spriteSheet != null)
- {
- var r = spriteSheet.rect;
- r.position = spriteSheet.rect.position - psdLayers[i].mosaicPosition + spriteData[k].position;
- spriteSheet.rect = r;
- spriteSheet.spritePosition = psdLayers[i].layerPosition + packOffsets[k];
- }
-
- if (spriteSheet != null)
- {
- spriteSheet.uvTransform = uvTransform[k];
- psdLayers[i].spriteID = spriteSheet.spriteID;
- psdLayers[i].mosaicPosition = spriteData[k].position;
- }
- }
- }
-
- foreach (var l in oldPsdLayers)
- l.Dispose();
- oldPsdLayers.Clear();
-
- oldPsdLayers.AddRange(psdLayers);
- importData.importedTextureHeight = textureActualHeight = height;
- importData.importedTextureWidth = textureActualWidth = width;
-
- var generatedTexture = ImportTexture(ctx, output, width, height, spriteImportData.ToArray());
-
- if (generatedTexture.texture)
- {
- importData.importedTextureHeight = generatedTexture.texture.height;
- importData.importedTextureWidth = generatedTexture.texture.width;
- }
-
- RegisterAssets(ctx, generatedTexture);
- }
- finally
- {
- if (output.IsCreated)
- output.Dispose();
- foreach (var l in oldPsdLayers)
- l.Dispose();
- }
- }
-
- void EnsureSingleSpriteExist()
- {
- if (m_SpriteImportData.Count <= 0)
- m_SpriteImportData.Add(new SpriteMetaData()); // insert default for single sprite mode
- }
-
- internal TextureImporterPlatformSettings GetPlatformTextureSettings(BuildTarget buildTarget)
- {
- var buildTargetName = TexturePlatformSettingsHelper.GetBuildTargetGroupName(buildTarget);
- TextureImporterPlatformSettings platformSettings = null;
- platformSettings = m_PlatformSettings.SingleOrDefault(x => x.name == buildTargetName && x.overridden == true);
- platformSettings = platformSettings ?? m_PlatformSettings.SingleOrDefault(x => x.name == TexturePlatformSettingsHelper.defaultPlatformName);
-
- if (platformSettings == null)
- {
- platformSettings = new TextureImporterPlatformSettings();
- platformSettings.name = buildTargetName;
- platformSettings.overridden = false;
- }
- return platformSettings;
- }
-
- void RegisterAssets(AssetImportContext ctx, TextureGenerationOutput output)
- {
- if ((output.sprites == null || output.sprites.Length == 0) && output.texture == null)
- {
- Debug.LogWarning("No Sprites or Texture are generated. Possibly because all layers in file are hidden", this);
- return;
- }
-
- SetPhysicsOutline(output.texture, output.sprites);
-
- UniqueNameGenerator assetNameHash = new UniqueNameGenerator();
- if (!string.IsNullOrEmpty(output.importInspectorWarnings))
- {
- Debug.LogWarning(output.importInspectorWarnings);
- }
- if (output.importWarnings != null && output.importWarnings.Length != 0)
- {
- foreach (var warning in output.importWarnings)
- Debug.LogWarning(warning);
- }
- if (output.thumbNail == null)
- Debug.LogWarning("Thumbnail generation fail");
- if (output.texture == null)
- {
- throw new Exception("Texture import fail");
- }
-
- var assetName = assetNameHash.GetUniqueName(System.IO.Path.GetFileNameWithoutExtension(ctx.assetPath), true, this);
- // Setup all fixed name on the hash table
- var registerTextureNameId = string.IsNullOrEmpty(m_TextureAssetName) ? "Texture" : m_TextureAssetName;
- var prefabRootNameId = string.IsNullOrEmpty(m_TextureAssetName) ? "root" : m_TextureAssetName;
- var registerPrefabNameId = string.IsNullOrEmpty(m_PrefabAssetName) ? "Prefab" : m_PrefabAssetName;
- var spriteLibAssetNameId = string.IsNullOrEmpty(m_SpriteLibAssetName) ? "SpriteLibAsset" : m_SpriteLibAssetName;
- var skeletonAssetNameId = string.IsNullOrEmpty(m_SkeletonAssetName) ? "SkeletonAsset" : m_SkeletonAssetName;
-
- output.texture.name = assetName;
- ctx.AddObjectToAsset(registerTextureNameId, output.texture, output.thumbNail);
- UnityEngine.Object mainAsset = output.texture;
-
-
- if (output.sprites != null)
- {
- var slAsset = ProduceSpriteLibAsset(output.sprites);
-
- if (shouldProduceGameObject)
- {
- GameObject prefab = null;
- if (m_PaperDollMode)
- prefab = OnProducePaperDollPrefab(prefabRootNameId, output.sprites, slAsset);
- else
- prefab = OnProducePrefab(prefabRootNameId, output.sprites, slAsset);
- if (prefab != null)
- {
- ctx.AddObjectToAsset(registerPrefabNameId, prefab);
- mainAsset = prefab;
- }
- }
-
- foreach (var s in output.sprites)
- {
- var spriteAssetName = assetNameHash.GetUniqueName(s.GetSpriteID().ToString(), false, s);
- ctx.AddObjectToAsset(spriteAssetName, s);
- }
-
- if (slAsset != null)
- {
- slAsset.name = assetName;
- ctx.AddObjectToAsset(spriteLibAssetNameId, slAsset);
- }
-
- if (characterMode && skeletonAsset == null)
- {
- var characterRig = ScriptableObject.CreateInstance<SkeletonAsset>();
- characterRig.name = assetName + " Skeleton";
- var bones = GetDataProvider<ICharacterDataProvider>().GetCharacterData().bones;
- characterRig.SetSpriteBones(bones);
- ctx.AddObjectToAsset(skeletonAssetNameId, characterRig);
- }
- }
- ctx.SetMainObject(mainAsset);
- }
-
- bool SpriteIsMainFromSpriteLib(string spriteId, out string categoryName)
- {
- categoryName = "";
- if (m_SpriteCategoryList.categories != null)
- {
- foreach (var category in m_SpriteCategoryList.categories)
- {
- var index = category.labels.FindIndex(x => x.spriteId == spriteId);
- if (index == 0)
- {
- categoryName = category.name;
- return true;
- }
- if (index > 0)
- return false;
- }
- }
- return true;
- }
-
- bool VisibleInHierarchy(List<PSDLayer> psdGroup, int index)
- {
- var psdLayer = psdGroup[index];
- var parentVisible = true;
- if (psdLayer.parentIndex >= 0)
- parentVisible = VisibleInHierarchy(psdGroup, psdLayer.parentIndex);
- return parentVisible && psdLayer.isVisible;
- }
-
- void BuildGroupGameObject(List<PSDLayer> psdGroup, int index, Transform root)
- {
- var psdData = psdGroup[index];
- if (psdData.gameObject == null)
- {
- var spriteImported = !psdGroup[index].spriteID.Empty() && psdGroup[index].isImported;
- var isVisibleGroup = psdData.isGroup && (VisibleInHierarchy(psdGroup, index) || m_ImportHiddenLayers) && m_GenerateGOHierarchy;
- if (spriteImported || isVisibleGroup)
- {
- var spriteData = GetSpriteImportData().FirstOrDefault(x => x.spriteID == psdData.spriteID);
- // Determine if need to create GameObject i.e. if the sprite is not in a SpriteLib or if it is the first one
- string categoryName;
- var b = SpriteIsMainFromSpriteLib(psdData.spriteID.ToString(), out categoryName);
- string goName = string.IsNullOrEmpty(categoryName) ? spriteData != null ? spriteData.name : psdData.name : categoryName;
- if (b)
- psdData.gameObject = m_GameObjectFactory.CreateGameObject(goName);
- }
- if (psdData.parentIndex >= 0 && m_GenerateGOHierarchy && psdData.gameObject != null)
- {
- BuildGroupGameObject(psdGroup, psdData.parentIndex, root);
- root = psdGroup[psdData.parentIndex].gameObject.transform;
- }
-
- if (psdData.gameObject != null)
- {
- psdData.gameObject.transform.SetParent(root);
- psdData.gameObject.transform.SetSiblingIndex(root.childCount-1);
- }
-
- }
- }
-
- bool shouldProduceGameObject
- {
- get { return m_CharacterMode && m_MosaicLayers && spriteImportMode == SpriteImportMode.Multiple; }
- }
-
- bool shouldResliceFromLayer
- {
- get { return m_ResliceFromLayer && m_MosaicLayers && spriteImportMode == SpriteImportMode.Multiple; }
- }
-
- bool characterMode
- {
- get { return mosaicMode && m_CharacterMode; }
- }
-
- float definitionScale
- {
- get
- {
- float definitionScaleW = importData.importedTextureWidth / (float)textureActualWidth;
- float definitionScaleH = importData.importedTextureHeight / (float)textureActualHeight;
- return Mathf.Min(definitionScaleW, definitionScaleH);
- }
- }
-
- internal static Vector2 GetPivotPoint(Rect rect, SpriteAlignment alignment, Vector2 customPivot)
- {
- switch (alignment)
- {
- case SpriteAlignment.TopLeft:
- return new Vector2(rect.xMin, rect.yMax);
-
- case SpriteAlignment.TopCenter:
- return new Vector2(rect.center.x, rect.yMax);
-
- case SpriteAlignment.TopRight:
- return new Vector2(rect.xMax, rect.yMax);
-
- case SpriteAlignment.LeftCenter:
- return new Vector2(rect.xMin, rect.center.y);
-
- case SpriteAlignment.Center:
- return new Vector2(rect.center.x, rect.center.y);
-
- case SpriteAlignment.RightCenter:
- return new Vector2(rect.xMax, rect.center.y);
-
- case SpriteAlignment.BottomLeft:
- return new Vector2(rect.xMin, rect.yMin);
-
- case SpriteAlignment.BottomCenter:
- return new Vector2(rect.center.x, rect.yMin);
-
- case SpriteAlignment.BottomRight:
- return new Vector2(rect.xMax, rect.yMin);
-
- case SpriteAlignment.Custom:
- return new Vector2(customPivot.x * rect.width, customPivot.y * rect.height);
- }
- return Vector2.zero;
- }
-
- void CreateBoneGO(int index, SpriteBone[] bones, BoneGO[] bonesGO, Transform defaultRoot)
- {
- if (bonesGO[index].go != null)
- return;
- var bone = bones[index];
- if (bone.parentId != -1 && bonesGO[bone.parentId].go == null)
- CreateBoneGO(bone.parentId, bones, bonesGO, defaultRoot);
-
- var go = m_GameObjectFactory.CreateGameObject(bone.name);
- if (bone.parentId == -1)
- go.transform.SetParent(defaultRoot);
- else
- go.transform.SetParent(bonesGO[bone.parentId].go.transform);
- go.transform.localPosition = bone.position * 1 / pixelsPerUnit;
- go.transform.localRotation = bone.rotation;
- bonesGO[index] = new BoneGO()
- {
- go = go,
- index = index
- };
- }
-
- BoneGO[] CreateBonesGO(Transform root)
- {
- if (characterMode)
- {
- var characterSkeleton = GetDataProvider<ICharacterDataProvider>().GetCharacterData();
- var bones = characterSkeleton.bones;
- if (bones != null)
- {
- var boneGOs = new BoneGO[bones.Length];
- for (int i = 0; i < bones.Length; ++i)
- {
- CreateBoneGO(i, bones, boneGOs, root);
- }
- return boneGOs;
- }
- }
- return new BoneGO[0];
- }
-
- void GetSpriteLiblabel(string spriteId, out string category, out string label)
- {
- category = "";
- label = "";
- var index = -1;
- foreach (var cat in m_SpriteCategoryList.categories)
- {
- index = cat.labels.FindIndex(x => x.spriteId == spriteId);
- if (index != -1)
- {
- category = cat.name;
- label = cat.labels[index].name;
- break;
- }
- }
- }
-
- GameObject OnProducePaperDollPrefab(string assetname, Sprite[] sprites, SpriteLibraryAsset spriteLib)
- {
- GameObject root = null;
- CharacterData? characterSkeleton = characterMode ? new CharacterData ? (GetDataProvider<ICharacterDataProvider>().GetCharacterData()) : null;
- if (sprites != null && sprites.Length > 0)
- {
- root = new GameObject();
- root.name = assetname + "_GO";
- var spriteImportData = GetSpriteImportData();
- var psdLayers = GetPSDLayers();
- var boneGOs = CreateBonesGO(root.transform);
- if (spriteLib != null)
- root.AddComponent<SpriteLibrary>().spriteLibraryAsset = spriteLib;
- var currentCharacterData = characterData;
- for (int i = 0; i < sprites.Length; ++i)
- {
- string categoryName;
- if (SpriteIsMainFromSpriteLib(sprites[i].GetSpriteID().ToString(), out categoryName))
- {
- var spriteBones = currentCharacterData.parts.FirstOrDefault(x => new GUID(x.spriteId) == sprites[i].GetSpriteID()).bones;
- var rootBone = root;
- if (spriteBones != null && spriteBones.Any())
- {
- var b = spriteBones.Where(x => x >= 0 && x < boneGOs.Length).Select(x => boneGOs[x]).OrderBy(x => x.index);
- if (b.Any())
- rootBone = b.First().go;
- }
-
- var srGameObject = m_GameObjectFactory.CreateGameObject(string.IsNullOrEmpty(categoryName) ? sprites[i].name : categoryName);
- var sr = srGameObject.AddComponent<SpriteRenderer>();
- sr.sprite = sprites[i];
- sr.sortingOrder = psdLayers.Count - psdLayers.FindIndex(x => x.spriteID == sprites[i].GetSpriteID());
- srGameObject.transform.parent = rootBone.transform;
- var spriteMetaData = spriteImportData.FirstOrDefault(x => x.spriteID == sprites[i].GetSpriteID());
- if (spriteMetaData != null)
- {
- var uvTransform = spriteMetaData.uvTransform;
- var outlineOffset = new Vector2(spriteMetaData.rect.x - uvTransform.x + (spriteMetaData.pivot.x * spriteMetaData.rect.width),
- spriteMetaData.rect.y - uvTransform.y + (spriteMetaData.pivot.y * spriteMetaData.rect.height)) * definitionScale / sprites[i].pixelsPerUnit;
- srGameObject.transform.position = new Vector3(outlineOffset.x, outlineOffset.y, 0);
- }
- var category = "";
- var labelName = "";
- GetSpriteLiblabel(sprites[i].GetSpriteID().ToString(), out category, out labelName);
- if (!string.IsNullOrEmpty(category) && !string.IsNullOrEmpty(labelName))
- {
- var sresolver = srGameObject.AddComponent<SpriteResolver>();
- sresolver.SetCategoryAndLabel(category, labelName);
- sresolver.ResolveSpriteToSpriteRenderer();
- }
- }
- }
- }
- return root;
- }
-
- internal void SetPlatformTextureSettings(TextureImporterPlatformSettings platformSettings)
- {
- var index = m_PlatformSettings.FindIndex(x => x.name == platformSettings.name);
- if(index < 0)
- m_PlatformSettings.Add(platformSettings);
- else
- m_PlatformSettings[index] = platformSettings;
- }
-
- internal TextureImporterPlatformSettings[] GetAllPlatformSettings()
- {
- return m_PlatformSettings.ToArray();
- }
-
- GameObject OnProducePrefab(string assetname, Sprite[] sprites, SpriteLibraryAsset spriteLib)
- {
- GameObject root = null;
- CharacterData? characterSkeleton = characterMode ? new CharacterData ? (GetDataProvider<ICharacterDataProvider>().GetCharacterData()) : null;
- if (sprites != null && sprites.Length > 0)
- {
- var currentCharacterData = characterData;
- var spriteImportData = GetSpriteImportData();
- root = new GameObject();
- root.transform.SetSiblingIndex(0);
- root.name = assetname + "_GO";
- if (spriteLib != null)
- root.AddComponent<SpriteLibrary>().spriteLibraryAsset = spriteLib;
-
- var psdLayers = GetPSDLayers();
- for (var i = 0; i < psdLayers.Count; ++i)
- {
- BuildGroupGameObject(psdLayers, i, root.transform);
- }
- var boneGOs = CreateBonesGO(root.transform);
- for (var i = 0; i < psdLayers.Count; ++i)
- {
- var l = psdLayers[i];
- var layerSpriteID = l.spriteID;
- var sprite = sprites.FirstOrDefault(x => x.GetSpriteID() == layerSpriteID);
- var spriteMetaData = spriteImportData.FirstOrDefault(x => x.spriteID == layerSpriteID);
- if (sprite != null && spriteMetaData != null && l.gameObject != null)
- {
- var spriteRenderer = l.gameObject.AddComponent<SpriteRenderer>();
- spriteRenderer.sprite = sprite;
- spriteRenderer.sortingOrder = psdLayers.Count - i;
-
- var pivot = spriteMetaData.pivot;
- pivot.x *= spriteMetaData.rect.width;
- pivot.y *= spriteMetaData.rect.height;
-
- var spritePosition = spriteMetaData.spritePosition;
- spritePosition.x += pivot.x;
- spritePosition.y += pivot.y;
- spritePosition *= (definitionScale / sprite.pixelsPerUnit);
-
- l.gameObject.transform.position = new Vector3(spritePosition.x, spritePosition.y, 0f);
-
- if (characterSkeleton != null)
- {
- var part = characterSkeleton.Value.parts.FirstOrDefault(x => x.spriteId == spriteMetaData.spriteID.ToString());
- if (part.bones != null && part.bones.Length > 0)
- {
- var spriteSkin = l.gameObject.AddComponent<SpriteSkin>();
- if (spriteRenderer.sprite != null && spriteRenderer.sprite.GetBindPoses().Length > 0)
- {
- var spriteBones = currentCharacterData.parts.FirstOrDefault(x => new GUID(x.spriteId) == spriteRenderer.sprite.GetSpriteID()).bones.Where(x => x >= 0 && x < boneGOs.Length).Select(x => boneGOs[x]);
- if (spriteBones.Any())
- {
- spriteSkin.rootBone = spriteBones.OrderBy(x => x.index).First().go.transform;
- spriteSkin.boneTransforms = spriteBones.Select(x => x.go.transform).ToArray();
- if (spriteSkin.isValid)
- spriteSkin.CalculateBounds();
- }
- }
- }
- }
-
- var category = "";
- var labelName = "";
- GetSpriteLiblabel(layerSpriteID.ToString(), out category, out labelName);
- if (!string.IsNullOrEmpty(category) && !string.IsNullOrEmpty(labelName))
- {
- var sresolver = l.gameObject.AddComponent<SpriteResolver>();
- sresolver.SetCategoryAndLabel(category, labelName);
- sresolver.ResolveSpriteToSpriteRenderer();
- }
- }
- }
-
- var prefabBounds = new Rect(0 , 0, importData.documentSize.x / pixelsPerUnit, importData.documentSize.y / pixelsPerUnit);
- var documentPivot = (Vector3)GetPivotPoint(prefabBounds, m_DocumentAlignment, m_DocumentPivot);
- for (int i = 0; i < psdLayers.Count; ++i)
- {
- var l = psdLayers[i];
- if (l.gameObject == null || l.gameObject.GetComponent<SpriteRenderer>() == null)
- continue;
- var p = l.gameObject.transform.localPosition;
- p -= documentPivot;
- l.gameObject.transform.localPosition = p;
- }
- for (int i = 0; i < boneGOs.Length; ++i)
- {
- if (boneGOs[i].go.transform.parent != root.transform)
- continue;
- var p = boneGOs[i].go.transform.position;
- p -= documentPivot;
- boneGOs[i].go.transform.position = p;
- }
- }
-
- return root;
- }
-
- Bounds? GetBoundingBox(GameObject root)
- {
- Bounds? prefabBounds1 = null;
- var sr = root.GetComponent<SpriteRenderer>();
- if (sr != null)
- {
- prefabBounds1 = sr.bounds;
- }
- for (int i = 0; i < root.transform.childCount; ++i)
- {
- var b = GetBoundingBox(root.transform.GetChild(i).gameObject);
- if (prefabBounds1 == null)
- prefabBounds1 = b;
- else
- {
- if (b.HasValue)
- {
- var bb = prefabBounds1.Value;
- bb.Encapsulate(b.Value);
- prefabBounds1 = bb;
- }
- }
- }
- return prefabBounds1;
- }
-
- bool CleanUpGameobjectsWithOutRig(GameObject root)
- {
- var sr = root.GetComponent<SpriteRenderer>();
- var canDelete = true;
- if (sr != null && sr.sprite != null)
- {
- try
- {
- var bones = GetDataProvider<ISpriteBoneDataProvider>().GetBones(sr.sprite.GetSpriteID());
- canDelete = bones == null || bones.Count == 0;
- }
- catch (Exception e)
- {
- Debug.LogError(e);
- }
- }
-
-
- List<GameObject> cleanup = new List<GameObject>();
- for (int i = 0; i < root.transform.childCount; ++i)
- {
- var go = root.transform.GetChild(i);
- if (CleanUpGameobjectsWithOutRig(go.gameObject))
- cleanup.Add(go.gameObject);
- }
-
- for (int i = 0; i < cleanup.Count; ++i)
- GameObject.DestroyImmediate(cleanup[i]);
- cleanup.Clear();
-
- if (root.transform.childCount == 0 && canDelete)
- return true;
-
- return false;
- }
-
-
-
- // ISpriteEditorDataProvider interface
- internal SpriteImportMode spriteImportMode
- {
- get
- {
- return m_TextureImporterSettings.textureType != TextureImporterType.Sprite ?
- SpriteImportMode.None :
- (SpriteImportMode)m_TextureImporterSettings.spriteMode;
- }
- }
-
- /// <summary>
- /// Implementation for ISpriteEditorDataProvider.pixelsPerUnit.
- /// </summary>
- SpriteImportMode ISpriteEditorDataProvider.spriteImportMode => spriteImportMode;
-
- internal int spriteDataCount
- {
- get
- {
- var spriteImportData = GetSpriteImportData();
- if (mosaicMode)
- return spriteImportData.Count;
- if (spriteImportMode != SpriteImportMode.Multiple)
- return 1;
- return spriteImportData.Count - 1;
- }
- }
-
- internal UnityEngine.Object targetObject
- {
- get { return this; }
- }
- UnityEngine.Object ISpriteEditorDataProvider.targetObject => targetObject;
-
- internal float pixelsPerUnit
- {
- get { return m_TextureImporterSettings.spritePixelsPerUnit; }
- }
-
- float ISpriteEditorDataProvider.pixelsPerUnit =>pixelsPerUnit;
-
- internal T GetDataProvider<T>() where T : class
- {
- if (typeof(T) == typeof(ISpriteBoneDataProvider))
- {
- return new SpriteBoneDataProvider { dataProvider = this } as T;
- }
- if (typeof(T) == typeof(ISpriteMeshDataProvider))
- {
- return new SpriteMeshDataProvider { dataProvider = this } as T;
- }
- if (typeof(T) == typeof(ISpriteOutlineDataProvider))
- {
- return new SpriteOutlineDataProvider { dataProvider = this } as T;
- }
- if (typeof(T) == typeof(ISpritePhysicsOutlineDataProvider))
- {
- return new SpritePhysicsOutlineProvider { dataProvider = this } as T;
- }
- if (typeof(T) == typeof(ITextureDataProvider))
- {
- return new TextureDataProvider { dataProvider = this } as T;
- }
- if (typeof(T) == typeof(ICharacterDataProvider))
- {
- return characterMode ? new CharacterDataProvider { dataProvider = this } as T : null;
- }
- if (typeof(T) == typeof(IMainSkeletonDataProvider))
- {
- return characterMode && skeletonAsset != null ? new MainSkeletonDataProvider() { dataProvider = this } as T : null;
- }
- if (typeof(T) == typeof(ISecondaryTextureDataProvider))
- {
- return new SecondaryTextureDataProvider() { dataProvider = this } as T;
- }
- else
- return this as T;
- }
-
- /// <summary>
- /// Implementation for ISpriteEditorDataProvider.GetDataProvider.
- /// </summary>
- /// <typeparam name="T">Data provider type to retrieve.</typeparam>
- /// <returns></returns>
- T ISpriteEditorDataProvider.GetDataProvider<T>()
- {
- return GetDataProvider<T>();
- }
-
- internal bool HasDataProvider(Type type)
- {
- if (characterMode)
- {
- if (type == typeof(ICharacterDataProvider))
- return true;
- if (type == typeof(IMainSkeletonDataProvider) && skeletonAsset != null)
- return true;
- }
- if (type == typeof(ISpriteBoneDataProvider) ||
- type == typeof(ISpriteMeshDataProvider) ||
- type == typeof(ISpriteOutlineDataProvider) ||
- type == typeof(ISpritePhysicsOutlineDataProvider) ||
- type == typeof(ITextureDataProvider) ||
- type == typeof(ISecondaryTextureDataProvider))
- {
- return true;
- }
- else
- return type.IsAssignableFrom(GetType());
- }
-
- /// <summary>
- /// Implementation for ISpriteEditorDataProvider.HasDataProvider.
- /// </summary>
- /// <param name="type">Data provider type to query.</param>
- /// <returns>True if data provider is supported, false otherwise.</returns>
- bool ISpriteEditorDataProvider.HasDataProvider(Type type)
- {
- return HasDataProvider(type);
- }
-
- internal void AddSpriteData(SpriteRect spriteRect)
- {
- if (spriteImportMode != SpriteImportMode.Multiple)
- Debug.LogWarning("Can only add sprite data when import mode is multiple");
- else
- {
- GetSpriteImportData().Add(new SpriteMetaData(spriteRect));
- }
- }
-
- internal void DeleteSpriteData(SpriteRect spriteRect)
- {
- if (spriteImportMode != SpriteImportMode.Multiple)
- Debug.LogWarning("Can only add sprite data when import mode is multiple");
- else
- {
- var spriteImportData = GetSpriteImportData();
- int index = spriteImportData.FindIndex(x => x.spriteID == spriteRect.spriteID);
- Assert.AreEqual(0, index, "Cannot delete Sprite from single sprite mode");
- spriteImportData.RemoveAt(index);
- }
- }
-
- internal int GetSpriteDataIndex(GUID guid)
- {
- switch (spriteImportMode)
- {
- case SpriteImportMode.Single:
- case SpriteImportMode.Polygon:
- return 0;
- case SpriteImportMode.Multiple:
- {
- var spriteImportData = GetSpriteImportData();
- return spriteImportData.FindIndex(x => x.spriteID == guid);
- }
- default:
- throw new InvalidOperationException("GUID not found");
- }
- }
-
- internal void Apply()
- {
- // Do this so that asset change save dialog will not show
- var originalValue = EditorPrefs.GetBool("VerifySavingAssets", false);
- EditorPrefs.SetBool("VerifySavingAssets", false);
- AssetDatabase.ForceReserializeAssets(new string[] { assetPath }, ForceReserializeAssetsOptions.ReserializeMetadata);
- EditorPrefs.SetBool("VerifySavingAssets", originalValue);
- }
-
- /// <summary>
- /// Implementation for ISpriteEditorDataProvider.Apply.
- /// </summary>
- void ISpriteEditorDataProvider.Apply()
- {
- Apply();
- }
-
- internal void InitSpriteEditorDataProvider() {}
-
- /// <summary>
- /// Implementation for ISpriteEditorDataProvider.InitSpriteEditorDataProvider.
- /// </summary>
- void ISpriteEditorDataProvider.InitSpriteEditorDataProvider()
- {
- InitSpriteEditorDataProvider();
- }
-
- internal SpriteRect[] GetSpriteRects()
- {
- var spriteImportData = GetSpriteImportData();
- var skip = mosaicMode ? 0 : 1;
- return spriteImportMode == SpriteImportMode.Multiple ? spriteImportData.Skip(skip).Select(x => new SpriteMetaData(x) as SpriteRect).ToArray() : new[] {new SpriteMetaData(spriteImportData[0]) };
- }
-
- /// <summary>
- /// Implementation for ISpriteEditorDataProvider.GetSpriteRects.
- /// </summary>
- /// <returns>An array of SpriteRect for the current import mode.</returns>
- SpriteRect[] ISpriteEditorDataProvider.GetSpriteRects()
- {
- return GetSpriteRects();
- }
-
- internal List<SpriteMetaData> GetSpriteImportData()
- {
- if (mosaicMode)
- {
- if (characterMode)
- {
- if (skeletonAsset != null)
- {
- return m_SharedRigSpriteImportData;
- }
- return m_RigSpriteImportData;
- }
- return m_MosaicSpriteImportData;
- }
- return m_SpriteImportData;
- }
-
- private SkeletonAsset skeletonAsset =>
- AssetDatabase.LoadAssetAtPath<SkeletonAsset>(AssetDatabase.GUIDToAssetPath(m_SkeletonAssetReferenceID));
-
- internal List<PSDLayer> GetPSDLayers()
- {
- if (mosaicMode)
- {
- if (characterMode)
- {
- if (skeletonAsset != null)
- return m_SharedRigPSDLayers;
- else
- return m_RigPSDLayers;
- }
- return m_MosaicPSDLayers;
- }
- return null;
- }
-
- internal SpriteMetaData[] GetSpriteMetaData()
- {
- var spriteImportData = GetSpriteImportData();
- var skip = mosaicMode ? 0 : 1;
- return spriteImportMode == SpriteImportMode.Multiple ? spriteImportData.Skip(skip).ToArray() : new[] { new SpriteMetaData(spriteImportData[0]) };
- }
-
- internal SpriteRect GetSpriteDataFromAllMode(GUID guid)
- {
- var spriteMetaData = m_RigSpriteImportData.FirstOrDefault(x => x.spriteID == guid);
- if(spriteMetaData == null)
- spriteMetaData = m_SharedRigSpriteImportData.FirstOrDefault(x => x.spriteID == guid);
- if(spriteMetaData == null)
- spriteMetaData = m_MosaicSpriteImportData.FirstOrDefault(x => x.spriteID == guid);
- if(spriteMetaData == null)
- spriteMetaData = m_SpriteImportData.FirstOrDefault(x => x.spriteID == guid);
- return spriteMetaData;
- }
-
- internal SpriteRect GetSpriteData(GUID guid)
- {
- var spriteImportData = GetSpriteImportData();
- var skip = mosaicMode ? 0 : 1;
- return spriteImportMode == SpriteImportMode.Multiple ? spriteImportData.Skip(skip).FirstOrDefault(x => x.spriteID == guid) : spriteImportData[0];
- }
-
- internal void SetSpriteRects(SpriteRect[] spriteRects)
- {
- var spriteImportData = GetSpriteImportData();
- if (spriteImportMode == SpriteImportMode.Multiple)
- {
- var singleSpriteID = mosaicMode ? new GUID() : spriteImportData[0].spriteID;
- spriteImportData.RemoveAll(data => data.spriteID != singleSpriteID && spriteRects.FirstOrDefault(x => x.spriteID == data.spriteID) == null);
- foreach (var sr in spriteRects)
- {
- var importData = spriteImportData.FirstOrDefault(x => x.spriteID == sr.spriteID);
- if (importData == null)
- spriteImportData.Add(new SpriteMetaData(sr));
- else
- {
- importData.name = sr.name;
- importData.alignment = sr.alignment;
- importData.border = sr.border;
- importData.pivot = sr.pivot;
- importData.rect = sr.rect;
- }
- }
- }
- else if (spriteRects.Length == 1 && (spriteImportMode == SpriteImportMode.Single || spriteImportMode == SpriteImportMode.Polygon))
- {
- if (spriteImportData[0].spriteID == spriteRects[0].spriteID)
- {
- spriteImportData[0].name = spriteRects[0].name;
- spriteImportData[0].alignment = spriteRects[0].alignment;
- m_TextureImporterSettings.spriteAlignment = (int)spriteRects[0].alignment;
- m_TextureImporterSettings.spriteBorder = spriteImportData[0].border = spriteRects[0].border;
- m_TextureImporterSettings.spritePivot = spriteImportData[0].pivot = spriteRects[0].pivot;
- spriteImportData[0].rect = spriteRects[0].rect;
- }
- else
- {
- spriteImportData[0] = new SpriteMetaData(spriteRects[0]);
- }
- }
- }
-
- /// <summary>
- /// Implementation for ISpriteEditorDataProvider.SetSpriteRects.
- /// </summary>
- /// <param name="spriteRects">Set the SpriteRect data for the current import mode.</param>
- void ISpriteEditorDataProvider.SetSpriteRects(SpriteRect[] spriteRects)
- {
- SetSpriteRects(spriteRects);
- }
-
- bool mosaicMode
- {
- get { return spriteImportMode == SpriteImportMode.Multiple && m_MosaicLayers; }
- }
-
- internal CharacterData characterData
- {
- get
- {
- if (skeletonAsset != null)
- return m_SharedRigCharacterData;
- return m_CharacterData;
- }
- set
- {
- if (skeletonAsset != null)
- m_SharedRigCharacterData = value;
- else
- m_CharacterData = value;
- }
- }
-
- internal Vector2Int canvasSize => importData.documentSize;
-
- SpriteLibraryAsset ProduceSpriteLibAsset(Sprite[] sprites)
- {
- if (!characterMode || m_SpriteCategoryList.categories == null)
- return null;
- var categories = m_SpriteCategoryList.categories.Select(x =>
- new SpriteLibCategory()
- {
- name = x.name,
- categoryList = x.labels.Select(y =>
- {
- var sprite = sprites.FirstOrDefault(z => z.GetSpriteID().ToString() == y.spriteId);
- return new SpriteCategoryEntry()
- {
- name = y.name,
- sprite = sprite
- };
- }).ToList()
- }).ToList();
- categories.RemoveAll(x => x.categoryList.Count == 0);
- if (categories.Count > 0)
- {
- // Always set version to 0 since we will never be updating this
- return SpriteLibraryAsset.CreateAsset(categories, "Sprite Lib", 0);
- }
- return null;
- }
-
- internal SecondarySpriteTexture[] secondaryTextures
- {
- get { return m_SecondarySpriteTextures; }
- set { m_SecondarySpriteTextures = value; }
- }
-
- internal void ReadTextureSettings(TextureImporterSettings dest)
- {
- m_TextureImporterSettings.CopyTo(dest);
- }
-
- internal SpriteBone[] mainSkeletonBones
- {
- get
- {
- var skeleton = skeletonAsset;
- return skeleton != null ? skeleton.GetSpriteBones() : null;
- }
- }
-
- internal IPSDLayerMappingStrategy GetLayerMappingStrategy()
- {
- return m_MappingCompare[(int)m_LayerMappingOption];
- }
-
- internal bool generatePhysicsOutline
- {
- get => m_GeneratePhysicsShape;
- }
-
- internal bool isNPOT
- {
- get => Mathf.IsPowerOfTwo(importData.textureActualWidth) && Mathf.IsPowerOfTwo(importData.textureActualHeight);
- }
- void SetPhysicsOutline(Texture2D texture, Sprite[] sprites)
- {
- var scale = definitionScale;
- var physicsOutlineDataProvider = GetDataProvider<ISpritePhysicsOutlineDataProvider>();
- foreach (var sprite in sprites)
- {
- var guid = sprite.GetSpriteID();
- var outline = physicsOutlineDataProvider.GetOutlines(guid);
-
- var outlineOffset = sprite.rect.size / 2;
- bool generated = false;
- if ((outline == null || outline.Count == 0) && generatePhysicsOutline)
- {
- Vector2[][] defaultOutline;
- InternalEditorBridge.GenerateOutlineFromSprite(sprite, 0.25f, 200, true, out defaultOutline);
- outline = new List<Vector2[]>(defaultOutline.Length);
- for (int i = 0; i < defaultOutline.Length; ++i)
- {
- outline.Add(defaultOutline[i]);
- }
-
- generated = true;
- }
- if (outline != null && outline.Count > 0)
- {
- // Ensure that outlines are all valid.
- int validOutlineCount = 0;
- for (int i = 0; i < outline.Count; ++i)
- validOutlineCount = validOutlineCount + ( (outline[i].Length > 2) ? 1 : 0 );
-
- int index = 0;
- var convertedOutline = new Vector2[validOutlineCount][];
- var useScale = generated ? pixelsPerUnit * scale : scale;
- var useOutlineOffset = generated ? Vector2.zero : outlineOffset;
- for (int i = 0; i < outline.Count; ++i)
- {
- if (outline[i].Length > 2)
- {
- convertedOutline[index] = new Vector2[outline[i].Length];
- for (int j = 0; j < outline[i].Length; ++j)
- {
- convertedOutline[index][j] = outline[i][j] * useScale + outlineOffset;
- }
- index++;
- }
- }
- sprite.OverridePhysicsShape(convertedOutline);
- }
- }
- }
- }
- }
|