Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
## [6.0.7] - 2022-12-01
### Fixed
- Fixed an issue where the amount of alpha removed from layers would not be re-applied as final position offset of the layers.
- Fixed an issue where an error would be shown when selecting Import Mode: Merged.
- Fixed an issue where the editor would crash when importing .psd/.psb files with their layers outside of the document canvas. (Case DANB-300)
- Fixed an issue where the generated GameObjects would be laid out differently from how they appear in the DCC tool. (Case DANB-298)
  • Loading branch information
Unity Technologies committed Dec 1, 2022
1 parent f1a2fb3 commit 8cf1940
Show file tree
Hide file tree
Showing 10 changed files with 501 additions and 149 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
# Changelog
## [6.0.7] - 2022-12-01
### Fixed
- Fixed an issue where the amount of alpha removed from layers would not be re-applied as final position offset of the layers.
- Fixed an issue where an error would be shown when selecting Import Mode: Merged.
- Fixed an issue where the editor would crash when importing .psd/.psb files with their layers outside of the document canvas. (Case DANB-300)
- Fixed an issue where the generated GameObjects would be laid out differently from how they appear in the DCC tool. (Case DANB-298)

## [6.0.6] - 2022-09-07
### Fixed
- Improved import speed and memory allocation for psd/psb files by reducing the intermediate texture buffers.
Expand Down
165 changes: 165 additions & 0 deletions Editor/PSDGameObjectPreviewData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityObject = UnityEngine.Object;

namespace UnityEditor.U2D.PSD
{
internal class PSDGameObjectPreviewData : IDisposable
{
static int s_SliderHash = "PSDGameObjectPreviewData_Slider".GetHashCode();
Texture m_Texture;
bool m_Disposed;
PreviewRenderUtility m_RenderUtility;
Rect m_PreviewRect = new Rect();
Vector2 m_PreviewDir = Vector2.zero;
GameObject m_PreviewObject;
string m_PrefabAssetPath;
Bounds m_RenderableBounds;
Vector2 m_GameObjectOffset;
GameObject m_Root;
Rect m_DocumentPivot;

public PSDGameObjectPreviewData(GameObject assetPrefab, Rect documentPivot)
{
m_RenderUtility = new PreviewRenderUtility();
m_RenderUtility.camera.fieldOfView = 30f;
m_Root = new GameObject();
m_PreviewObject = GameObject.Instantiate(assetPrefab, Vector3.zero, Quaternion.identity);
m_PreviewObject.transform.parent = m_Root.transform;
m_DocumentPivot = documentPivot;
m_RenderUtility.AddSingleGO(m_Root);
}

static Vector2 Drag2D(Vector2 scrollPosition, Rect position)
{
int controlId = GUIUtility.GetControlID(s_SliderHash, FocusType.Passive);
var current = Event.current;
switch (current.GetTypeForControl(controlId))
{
case UnityEngine.EventType.MouseDown:
if (position.Contains(current.mousePosition) && (double)position.width > 50.0)
{
GUIUtility.hotControl = controlId;
current.Use();
EditorGUIUtility.SetWantsMouseJumping(1);
break;
}

break;
case UnityEngine.EventType.MouseUp:
if (GUIUtility.hotControl == controlId)
GUIUtility.hotControl = 0;
EditorGUIUtility.SetWantsMouseJumping(0);
break;
case UnityEngine.EventType.MouseDrag:
if (GUIUtility.hotControl == controlId)
{
scrollPosition -= current.delta * (current.shift ? 3f : 1f) / Mathf.Min(position.width, position.height) * 140f;
current.Use();
GUI.changed = true;
break;
}
break;
}
return scrollPosition;
}

public void DrawPreview(Rect r, GUIStyle background, Vector2 offset, bool showPivot)
{
if (!ShaderUtil.hardwareSupportsRectRenderTexture)
{
if (Event.current.type != UnityEngine.EventType.Repaint)
return;
EditorGUI.DropShadowLabel(new Rect(r.x, r.y, r.width, 40f), "Preview requires\nrender texture support");
}
else
{

Vector2 vector2 = Drag2D(m_PreviewDir, r);
if (vector2 != m_PreviewDir)
{
UnityEngine.Object.DestroyImmediate(m_Texture);
m_Texture = null;
m_PreviewDir = vector2;
}


if (m_GameObjectOffset != offset)
{
UnityEngine.Object.DestroyImmediate(m_Texture);
m_Texture = null;
m_GameObjectOffset = offset;
}

if (Event.current.type != EventType.Repaint)
return;

if (m_PreviewRect != r)
{
UnityEngine.Object.DestroyImmediate(m_Texture);
m_Texture = null;
m_PreviewRect = r;
}

if (m_Texture == null)
{
m_PreviewObject.transform.position = Vector2.zero;
m_RenderUtility.BeginPreview(r, background);
DoRenderPreview();
m_Texture = m_RenderUtility.EndPreview();
}

GUI.DrawTexture(r, m_Texture, ScaleMode.StretchToFill, false);
}
}

void DoRenderPreview()
{
m_RenderableBounds = GetRenderableBounds(m_Root);
float num1 = Mathf.Max(m_RenderableBounds.extents.magnitude, 0.0001f);
float num2 = num1 * 3.8f;
Quaternion quaternion = Quaternion.Euler(-m_PreviewDir.y, -m_PreviewDir.x, 0.0f);
Vector3 vector3 = m_RenderableBounds.center - quaternion * (Vector3.forward * num2);
m_RenderUtility.camera.transform.position = vector3;
m_RenderUtility.camera.transform.rotation = quaternion;
m_RenderUtility.camera.nearClipPlane = num2 - num1 * 1.1f;
m_RenderUtility.camera.farClipPlane = num2 + num1 * 5.1f;
m_RenderUtility.lights[0].intensity = 0.7f;
m_RenderUtility.lights[0].transform.rotation = quaternion * Quaternion.Euler(40f, 40f, 0.0f);
m_RenderUtility.lights[1].intensity = 0.7f;
m_RenderUtility.lights[1].transform.rotation = quaternion * Quaternion.Euler(340f, 218f, 177f);
m_RenderUtility.ambientColor = new Color(0.1f, 0.1f, 0.1f, 0.0f);

m_RenderUtility.Render(true);
}

public static Bounds GetRenderableBounds(GameObject go)
{
Bounds bounds = new Bounds();
if (go == null)
return bounds;
var renderers = new List<Renderer>();
go.GetComponentsInChildren(renderers);
foreach (Renderer rendererComponents in renderers)
{
if (bounds.extents == Vector3.zero)
bounds = rendererComponents.bounds;
else if(rendererComponents.enabled)
bounds.Encapsulate(rendererComponents.bounds);
}
return bounds;
}

public void Dispose()
{
if (m_Disposed)
return;
m_RenderUtility.Cleanup();
UnityEngine.Object.DestroyImmediate(m_PreviewObject);
m_PreviewObject = null;
m_Disposed = true;
}
}

}
3 changes: 3 additions & 0 deletions Editor/PSDGameObjectPreviewData.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 11 additions & 9 deletions Editor/PSDImporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace UnityEditor.U2D.PSD
/// ScriptedImporter to import Photoshop files
/// </summary>
// Version using unity release + 5 digit padding for future upgrade. Eg 2021.2 -> 21200000
[ScriptedImporter(21200002, "psb", AllowCaching = true)]
[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
Expand Down Expand Up @@ -246,7 +246,7 @@ public override void OnImportAsset(AssetImportContext ctx)
try
{
var spriteImportData = GetSpriteImportData();
FlattenImageTask.Execute(m_ExtractData, ref outputImageBuffer, m_ImportHiddenLayers, documentSize);
FlattenImageTask.Execute(m_ExtractData, ref outputImageBuffer, m_ImportHiddenLayers, canvasSize);

if (spriteImportData.Count <= 0 || spriteImportData[0] == null)
{
Expand Down Expand Up @@ -512,7 +512,7 @@ void ImportFromLayers(AssetImportContext ctx)
List<PSDLayer> psdLayers = null;
try
{
ExtractLayerTask.Execute(in m_ExtractData, out psdLayers, m_ImportHiddenLayers, documentSize);
ExtractLayerTask.Execute(in m_ExtractData, out psdLayers, m_ImportHiddenLayers, canvasSize);

var mappingStrategy = GetLayerMappingStrategy();
var layerUnique = mappingStrategy.LayersUnique(psdLayers.ConvertAll(x => (IPSDLayerMappingStrategyComparable)x));
Expand Down Expand Up @@ -564,6 +564,10 @@ void ImportFromLayers(AssetImportContext ctx)
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)
{
Expand Down Expand Up @@ -591,12 +595,11 @@ void ImportFromLayers(AssetImportContext ctx)

psdLayer.spriteName = GetUniqueSpriteName(psdLayer.name, spriteNameHash);
spriteSheet.name = psdLayer.spriteName;
spriteSheet.spritePosition = psdLayer.layerPosition;
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;
Expand Down Expand Up @@ -659,9 +662,8 @@ void ImportFromLayers(AssetImportContext ctx)
{
var r = spriteSheet.rect;
r.position = spriteSheet.rect.position - psdLayers[i].mosaicPosition + spriteData[k].position;

spriteSheet.rect = r;
spriteSheet.spritePosition = psdLayers[i].layerPosition;
spriteSheet.spritePosition = psdLayers[i].layerPosition + packOffsets[k];
}

if (spriteSheet != null)
Expand Down Expand Up @@ -1556,7 +1558,7 @@ internal CharacterData characterData
}
}

internal Vector2Int documentSize => importData.documentSize;
internal Vector2Int canvasSize => importData.documentSize;

SpriteLibraryAsset ProduceSpriteLibAsset(Sprite[] sprites)
{
Expand Down
2 changes: 1 addition & 1 deletion Editor/PSDImporterDataProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ public CharacterData GetCharacterData()

parts.Reverse();
cd.parts = parts.ToArray();
cd.dimension = dataProvider.documentSize;
cd.dimension = dataProvider.canvasSize;
cd.characterGroups = groups.ToArray();
return cd;
}
Expand Down
57 changes: 57 additions & 0 deletions Editor/PSDImporterEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ struct InspectorGUI
PSDImporterEditorLayerTreeView m_LayerTreeView;
TreeViewState m_TreeViewState;
PSDImporter m_CurrentTarget;
PSDGameObjectPreviewData m_PreviewRenderUtility;
/// <summary>
/// Implementation of AssetImporterEditor.OnEnable
/// </summary>
Expand Down Expand Up @@ -183,6 +184,7 @@ public override void OnEnable()
};
m_TreeViewState = new TreeViewState();
UpdateLayerTreeView();
InitPreview();
}

/// <summary>
Expand All @@ -207,6 +209,37 @@ protected override void InitializeExtraDataInstance(UnityEngine.Object extraTarg

}

void InitPreview()
{
var t = (PSDImporter)target;
var gameObject = AssetDatabase.LoadAssetAtPath<GameObject>(t.assetPath);

if (m_PreviewRenderUtility != null)
{
m_PreviewRenderUtility.Dispose();
m_PreviewRenderUtility = null;
}

if (gameObject != null)
{
var documentSize = new Rect(0, 0, t.importData.documentSize.x / t.pixelsPerUnit, t.importData.documentSize.y / t.pixelsPerUnit);
m_PreviewRenderUtility = new PSDGameObjectPreviewData(gameObject, documentSize);
}
}

/// <summary>
/// Implmentation of AssetImporterEditor.OnDisable
/// </summary>
public override void OnDisable()
{
base.OnDisable();
if (m_PreviewRenderUtility != null)
{
m_PreviewRenderUtility.Dispose();
m_PreviewRenderUtility = null;
}
}

void UpdateLayerTreeView()
{
if (!ReferenceEquals(m_CurrentTarget,target) || m_LayerTreeView == null)
Expand Down Expand Up @@ -345,6 +378,11 @@ protected override void Apply()
ApplyTexturePlatformSettings();
base.Apply();
PSDImportPostProcessor.currentApplyAssetPath = ((PSDImporter) target).assetPath;
if (m_PreviewRenderUtility != null)
{
m_PreviewRenderUtility.Dispose();
m_PreviewRenderUtility = null;
}
}

void ApplyTexturePlatformSettings()
Expand Down Expand Up @@ -1140,6 +1178,25 @@ public override bool HasModified()
return m_TexturePlatformSettingsHelper.HasModified();
}

/// <summary>
/// Override from AssetImporterEditor to show custom preview.
/// </summary>
/// <param name="r">Preview Rect.</param>
public override void DrawPreview(Rect r)
{
if (m_PreviewRenderUtility == null)
InitPreview();

if (m_PreviewRenderUtility != null)
{
var t = (PSDImporter)target;
var prefabBounds = new Rect(0 , 0, t.importData.documentSize.x/ t.pixelsPerUnit, t.importData.documentSize.y/ t.pixelsPerUnit);
m_PreviewRenderUtility.DrawPreview(r, "PreBackgroundSolid", prefabBounds.center, false);
}
else
base.DrawPreview(r);
}

internal class Styles
{
public readonly GUIContent textureTypeTitle = new GUIContent("Texture Type", "What will this texture be used for?");
Expand Down
19 changes: 19 additions & 0 deletions Editor/PSDLayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,25 @@ public PSDLayer(NativeArray<Color32> tex, int parent, bool group, string layerNa
m_SpriteID = new GUID().ToString();
}

public PSDLayer(PSDLayer layer)
{
m_Name = layer.m_Name;
m_SpriteName = layer.m_SpriteName;
m_IsGroup = layer.m_IsGroup;
m_ParentIndex = layer.m_ParentIndex;
m_SpriteID = layer.m_SpriteID;
m_LayerID = layer.m_LayerID;
m_MosaicPosition = layer.m_MosaicPosition;
m_Flatten = layer.m_Flatten;
m_IsImported = layer.m_IsImported;
m_IsVisible = layer.m_IsVisible;
m_LayerPosition = layer.m_LayerPosition;
m_GameObject = layer.m_GameObject;
width = layer.width;
height = layer.height;
texture = layer.texture;
}

public bool isVisible => m_IsVisible;
public int layerID { get { return m_LayerID; } private set { m_LayerID = value; } }

Expand Down
Loading

0 comments on commit 8cf1940

Please sign in to comment.