Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
## [10.0.0] - 2024-12-09
### Added
- Added support for Sprite Frame Editing capabilities where data that are from the source file are locked by default.
- Added new ability to generate Tile asset and Tile Palette from PSDImporter.
  • Loading branch information
Unity Technologies committed Dec 9, 2024
1 parent f0daf2a commit d23049b
Show file tree
Hide file tree
Showing 17 changed files with 584 additions and 103 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## [10.0.0] - 2024-12-09
### Added
- Added support for Sprite Frame Editing capabilities where data that are from the source file are locked by default.
- Added new ability to generate Tile asset and Tile Palette from PSDImporter.

## [9.0.3] - 2024-04-01
### Fixed
- Fix source file cannot be deleted after subsequent import. (Case DANB-579)
Expand Down
7 changes: 6 additions & 1 deletion Documentation~/PSD-importer-properties.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#PSD Importer Inspector properties
The PSD Importer is available after you import a .psb file into your Project. Select the .psb Asset file and set its **Texture Type** to [Sprite (2D and UI)](https://docs.unity3d.com/Manual/TextureTypes.html#Sprite). The PSD Importer properties are split between two main tabs, with the following properties available.

![](images/psdimporter-properties-22.2.png) <br/>PSD Importer Inspector properties
![](images/psdimporter-properties-6000.1.png) <br/>PSD Importer Inspector properties

##Settings tab
The Settings tab allows you to customize how the PSD Importer imports a file. The settings are categorized into individual section fold-outs.
Expand Down Expand Up @@ -201,6 +201,11 @@ If there is no .skeleton Asset assigned to the importer’s **Main Skeleton** pr

When you open and edit the character in 2D Animation package’s **Skinning Editor**, the module will display the bone hierarchy provided by the skeleton Asset assigned to **Main Skeleton** for rigging.

###Tile Palette
The following section allows generating Tile assets and Tile Palette where each layer in the source file will also generate a tile asset

![](images/tilepalette-6000.1.png)

##Layer Management Tab
The **Layer Management Tab** allows you to customize how the Importer imports the layers from the Photoshop file.

Expand Down
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Documentation~/images/tilepalette-6000.1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion Documentation~/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ The different versions of the PSD Importer package are supported by the followin

Package version | Unity Editor version
--|--
9.x.x | 2023.1
10.x.x | 6000.1
9.x.x | 2023.1 up to 6000.0
8.x.x | 2022.2
7.x.x | 2022.1
6.x.x | 2021.2 or 2021.3
Expand Down
11 changes: 4 additions & 7 deletions Documentation~/whats-new.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
# What's new in version 9.0
# What's new in version 10.0

## Improved
- Faster imports of .psd/.psb files. The update will be particularly noticable when importing files with many layers.
- Reduced the memory overhead when importing a .psd/.psb file.

## Updated
- Reduced the number of [Sprite Rect Data](PSD-importer-SpriteRect.md) containers, from five to three.
## Added
- Added support for Sprite Frame Editing capabilities where data that are from the source file are locked by default.
- Added new ability to generate Tile asset and Tile Palette from PSDImporter.
8 changes: 8 additions & 0 deletions Editor/PSDImportData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ public int textureActualWidth
set => m_TextureActualWidth = value;
}

[SerializeField]
TextureImporterSettings m_SingleSpriteTextureImporterSettings;
public TextureImporterSettings singleSpriteTextureImporterSettings
{
get => m_SingleSpriteTextureImporterSettings;
set => m_SingleSpriteTextureImporterSettings = value;
}

[SerializeField]
PSDLayerData[] m_PsdLayerData;
public PSDLayerData[] psdLayerData => m_PsdLayerData;
Expand Down
195 changes: 186 additions & 9 deletions Editor/PSDImporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
using UnityEngine.U2D;
using UnityEngine.Scripting.APIUpdating;

#if ENABLE_2D_TILEMAP_EDITOR
using UnityEditor.Tilemaps;
using UnityEngine.Tilemaps;
#endif

#if ENABLE_2D_ANIMATION
using UnityEditor.U2D.Animation;
using UnityEngine.U2D.Animation;
Expand Down Expand Up @@ -149,6 +154,38 @@ internal enum ELayerMappingOption
[SerializeField]
bool m_KeepDupilcateSpriteName = true;

#if ENABLE_2D_TILEMAP_EDITOR
[SerializeField]
bool m_GenerateTileAssets = false;

[SerializeField]
GridLayout.CellLayout m_TilePaletteCellLayout = GridLayout.CellLayout.Rectangle;

private static readonly GridLayout.CellSwizzle[] s_TilePaletteexagonSwizzleTypeValue =
{
GridLayout.CellSwizzle.XYZ,
GridLayout.CellSwizzle.YXZ,
};

[SerializeField]
int m_TilePaletteHexagonLayout;

[SerializeField]
Vector3 m_TilePaletteCellSize = new Vector3(1, 1, 0);

[SerializeField]
GridPalette.CellSizing m_TilePaletteCellSizing = GridPalette.CellSizing.Automatic;

[SerializeField]
TransparencySortMode m_TransparencySortMode = TransparencySortMode.Default;

[SerializeField]
Vector3 m_TransparencySortAxis = new Vector3(0f, 0f, 1f);

[SerializeField]
TileTemplate m_TileTemplate = null;
#endif

[SerializeField]
int m_Padding = 4;

Expand Down Expand Up @@ -546,16 +583,83 @@ TextureGenerationOutput ImportFlattenImage(Document doc, AssetImportContext ctx)
{
FlattenImageTask.Execute(m_ExtractData, ref outputImageBuffer, m_ImportHiddenLayers, canvasSize);

m_SingleSpriteImportData[0].name = System.IO.Path.GetFileNameWithoutExtension(ctx.assetPath) + "_1";
m_SingleSpriteImportData[0].alignment = (SpriteAlignment)m_TextureImporterSettings.spriteAlignment;
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);

m_ImportData.singleSpriteTextureImporterSettings = m_TextureImporterSettings;
importData.importedTextureWidth = textureActualWidth = doc.width;
importData.importedTextureHeight = textureActualHeight = doc.height;

var spriteImportData = GetSpriteImportData();
if (m_ResliceFromLayer)
{
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 layerIndex = new List<int>();
var spriteData = new List<RectInt>();
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)
{
layerIndex.Add(i);
var rect = new RectInt((int) l.layerPosition.x, (int) l.layerPosition.y, l.width, l.height);
spriteData.Add(rect);
}
}

var newSpriteMeta = new List<SpriteMetaData>();

for (int i = 0; i < spriteData.Count && 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 = ImportUtilities.GetUniqueSpriteName(psdLayer.name, spriteNameHash, m_KeepDupilcateSpriteName);
spriteSheet.name = psdLayer.spriteName;
spriteSheet.spritePosition = psdLayer.layerPosition;

spriteSheet.rect = new Rect(spriteData[i].x, spriteData[i].y, spriteData[i].width, spriteData[i].height);

psdLayer.spriteID = spriteSheet.spriteID;
psdLayer.mosaicPosition = spriteData[i].position;
newSpriteMeta.Add(spriteSheet);
}
spriteImportData.Clear();
spriteImportData.AddRange(newSpriteMeta);
}
finally
{
if (psdLayers != null)
foreach (var l in psdLayers)
l.Dispose();
}
}

output = ImportTexture(ctx, outputImageBuffer, doc.width, doc.height, spriteImportData.ToArray());
importData.importedTextureWidth = output.texture.width;
importData.importedTextureHeight = output.texture.height;
Expand Down Expand Up @@ -866,6 +970,7 @@ void RegisterAssets(AssetImportContext ctx, TextureGenerationOutput output)
RegisterGameObjects(ctx, output, ref mainAsset);
RegisterSprites(ctx, output, assetNameGenerator);
RegisterSkeletonAsset(ctx, output, assetName);
RegisterTilemapAsset(ctx, output, assetName, ref mainAsset);
ctx.SetMainObject(mainAsset);
}

Expand Down Expand Up @@ -957,6 +1062,59 @@ void RegisterSkeletonAsset(AssetImportContext ctx, TextureGenerationOutput outpu
#endif
}

void RegisterTilemapAsset(AssetImportContext ctx
, TextureGenerationOutput output
, string assetName
, ref UnityEngine.Object mainAsset)
{
if (output.texture == null)
return;

if (output.sprites == null)
return;

#if ENABLE_2D_TILEMAP_EDITOR
if (!m_GenerateTileAssets)
return;

var sprites = new List<Sprite>();
foreach (var s in output.sprites)
{
if(s.rect.width > 4 && s.rect.height > 4)
sprites.Add(s);
}
var paletteGO = GridPaletteUtility.CreateNewPaletteAsSubAsset(assetName
, m_TilePaletteCellLayout
, m_TilePaletteCellSizing
, m_TilePaletteCellSize
, s_TilePaletteexagonSwizzleTypeValue[m_TilePaletteHexagonLayout]
, m_TransparencySortMode
, m_TransparencySortAxis
, new [] { output.texture }
, new [] { sprites }
, new [] { m_TileTemplate }
, out var palette
, out var tiles);

ctx.AddObjectToAsset("GridPalette", palette);
foreach (var tile in tiles)
{
// Use Sprite ID + Tile for pure Tile
if (tile is Tile t && t.sprite != null)
{
ctx.AddObjectToAsset($"{t.sprite.GetSpriteID()} Tile", tile);
}
else
{
ctx.AddObjectToAsset(tile.name, tile);
}
}

ctx.AddObjectToAsset("Palette", paletteGO);
mainAsset = paletteGO;
#endif
}

void BuildGroupGameObject(List<PSDLayer> psdGroup, int index, Transform root)
{
var psdData = psdGroup[index];
Expand Down Expand Up @@ -1278,7 +1436,7 @@ List<SpriteMetaData> GetSpriteImportData()
return m_MultiSpriteImportData;
}

return m_SingleSpriteImportData;
return new List<SpriteMetaData> { GetSingleSpriteImportData() };
}

internal SpriteMetaData[] GetSpriteMetaData()
Expand All @@ -1290,7 +1448,7 @@ internal SpriteMetaData[] GetSpriteMetaData()
return m_MultiSpriteImportData.ToArray();
}

return new[] { new SpriteMetaData(m_SingleSpriteImportData[0]) };
return new[] { GetSingleSpriteImportData() };
}

internal SpriteRect GetSpriteData(GUID guid)
Expand All @@ -1302,7 +1460,26 @@ internal SpriteRect GetSpriteData(GUID guid)
return m_MultiSpriteImportData.FirstOrDefault(x => x.spriteID == guid);
}

return m_SingleSpriteImportData[0];
return GetSingleSpriteImportData();
}

SpriteMetaData GetSingleSpriteImportData()
{
SpriteMetaData spriteMetaData = new SpriteMetaData();
spriteMetaData.spriteID = AssetDatabase.GUIDFromAssetPath(assetPath);
if(m_SingleSpriteImportData == null || m_SingleSpriteImportData.Count < 1 && m_SingleSpriteImportData[0] != null)
spriteMetaData.Copy(m_SingleSpriteImportData[0]);
if(assetPath != null)
spriteMetaData.name = System.IO.Path.GetFileNameWithoutExtension(assetPath) + "_1";
if (importData != null)
{
spriteMetaData.rect = new Rect(0, 0, importData.importedTextureWidth, importData.importedTextureHeight);
spriteMetaData.pivot = m_TextureImporterSettings.spritePivot;
spriteMetaData.alignment = (SpriteAlignment)m_TextureImporterSettings.spriteAlignment;
spriteMetaData.border = m_TextureImporterSettings.spriteBorder;
}

return spriteMetaData;
}

internal Vector2 GetDocumentPivot()
Expand Down
Loading

0 comments on commit d23049b

Please sign in to comment.