Search Unity

PSD Importer and Secondary Textures

Discussion in '2D' started by DannyWood, Jan 29, 2020.

  1. DannyWood

    DannyWood

    Joined:
    Jun 5, 2018
    Posts:
    2
    I am trying to figure out how to use the PSD Importer with Secondary Textures. I have Imported my PSB files and everything looks great and have it rigged but since The importer slices, the file internally how do I add a Normal Map based on that newly organized slices?

    Am I missing the ability to export the file, create a normal map, then import it as a secondary map?

    Thanks.
     
  2. aztno12

    aztno12

    Joined:
    Feb 5, 2020
    Posts:
    1
    Hey, I did some googling and made this script for exporting the sliced texture. You can find the sliced texture by expanding the PSD imported sprite. Make sure you also enable write/read for the sprite, this is under the advanced section. This script should appear in unity under the window section, so in unity go to window -> Export Sliced Texture. Then just drag in the sliced texture, give it a name and press the button.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEditor;
    5.  
    6. public class ExportSlicedTexture : EditorWindow
    7. {
    8.     private Texture2D texture;
    9.     private string name;
    10.     [MenuItem("Window/Export Sliced Texture")]
    11.     public static void ShowWindow()
    12.     {
    13.         GetWindow<ExportSlicedTexture>("Export Sliced Texture");
    14.     }
    15.  
    16.     private void OnGUI()
    17.     {
    18.         texture = (Texture2D)EditorGUILayout.ObjectField(texture, typeof(Texture2D), allowSceneObjects: false);
    19.         name = EditorGUILayout.TextField("File name: ", name);
    20.         if (GUILayout.Button("Run Function") && texture != null)
    21.         {
    22.             SaveTextureAsPNG(texture, name);
    23.         }
    24.     }
    25.  
    26.     public static void SaveTextureAsPNG(Texture2D texture, string fileName)
    27.     {
    28.         byte[] _bytes = texture.EncodeToPNG();
    29.         var dirPath = Application.dataPath + "/Sprite Sheets/";
    30.         if (!System.IO.Directory.Exists(dirPath))
    31.         {
    32.             System.IO.Directory.CreateDirectory(dirPath);
    33.         }
    34.         System.IO.File.WriteAllBytes(dirPath + fileName + ".png", _bytes);
    35.         Debug.Log(_bytes.Length / 1024 + "Kb was saved as: " + fileName + ".png");
    36.     }
    37. }
     
    Imaginesto, r35, pry_bar and 6 others like this.
  3. DannyWood

    DannyWood

    Joined:
    Jun 5, 2018
    Posts:
    2
    I really appreciate the code work, that is close to what I want, But your code can't read the PSB file, I am trying to get the file that Unity creates after you go into the Sprite Editor, and it has organized your Character into a Sprite Sheet. I am assuming that is what I need to make secondary Texture Normal Map. I feel like that the new PSB Importer plugin has the Key.
     

    Attached Files:

  4. marcarasanz

    marcarasanz

    Joined:
    Aug 23, 2019
    Posts:
    20
    Up,

    Hi, am in the same problem. I have some psb files in Unity, all fine, but how can i take off that file that Unity creates to make the normal map? I tried using just .psd but is a lot of work to rig in that way. @ DannyWood have you been success with your trouble?
     
  5. Generic_Username_12345

    Generic_Username_12345

    Joined:
    Jul 18, 2017
    Posts:
    3
    I have the same problem ((( is anybody there? Help us!!!
     
  6. a-type

    a-type

    Joined:
    Mar 29, 2020
    Posts:
    1
    Thanks for this, but I found it didn't work in my case after following instructions.

    The script threw errors:

    Code (CSharp):
    1. Unsupported texture format - Texture2D::EncodeTo functions do not support compressed texture formats.
    2. UnityEngine.ImageConversion:EncodeToPNG(Texture2D)
    3. ExportSlicedTexture:SaveTextureAsPNG(Texture2D, String) (at Assets/Editor/ExportSlicedTexture.cs:28)
    4. ExportSlicedTexture:OnGUI() (at Assets/Editor/ExportSlicedTexture.cs:22)
    5. UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)
    6.  
    7. NullReferenceException: Object reference not set to an instance of an object
    8. System.IO.File.WriteAllBytes (System.String path, System.Byte[] bytes) (at <437ba245d8404784b9fbab9b439ac908>:0)
    9. ExportSlicedTexture.SaveTextureAsPNG (UnityEngine.Texture2D texture, System.String fileName) (at Assets/Editor/ExportSlicedTexture.cs:34)
    10. ExportSlicedTexture.OnGUI () (at Assets/Editor/ExportSlicedTexture.cs:22)
    11. System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <437ba245d8404784b9fbab9b439ac908>:0)
    12. Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
    13.  
    14. [...]
    It's a start, at least. If I can figure out how to get it fixed I'll post.

    Is there any known workflow for creating normalmaps for PSB sprites? I tried copying the PSB and generating normalmaps in Photoshop (Filter > 3D > Generate normal maps), but the automated ones don't really work for my sprites. I'll need to find a way to do manual lightmapping on the sprites and run them through an external tool, but that's not possible without the sliced image.

    The sliced image appears to be in the format "Compressed RGBA DTX5 sRGB"

    UPDATE: It's working. I disabled compression on the original asset (Platform Settings in the inspector).

    Update 2: I have a workflow! Laigter processed the exported texture perfectly, and lighting now looks about where I want it for my 2d rigged character!
     
    Last edited: Apr 1, 2020
    Xiangting_Su and puergames like this.
  7. ananthn

    ananthn

    Joined:
    May 7, 2019
    Posts:
    2
    I copied the code & the "Exported Sliced Texture" is appearing in my window.

    I have tried
    Disabled the Compression
    Made sprite read/write enabled

    But I am not able to drag the sliced sprite into the "Exported Sliced Texture" Texture input box.

    Any solutions found or workflow...???

    Your help is much appreciated.
     
  8. Xiangting_Su

    Xiangting_Su

    Unity Technologies

    Joined:
    Sep 22, 2020
    Posts:
    253
    Oh that's great news! :D

    Could you share your tips/workflow on how you got that to work between Unity and Laigter? Did you use the same PSB file (for diffuse) which you sliced and rigged and duplicated it for the secondary textures?
     
  9. RequiemOfTheSun

    RequiemOfTheSun

    Joined:
    Sep 16, 2012
    Posts:
    4
    This thread really helped me out.

    My process was:
    1. Set Compression to 'None'
    2. Make the sprite 'Read/Write Enabled'
    3. Drag the Split image from the PSD/PSB import children into the script tool window
    4. Generate sliced image
    5. Create normal map from sliced image (tool 'Sprite Illuminator')
    6. Use as normal map secondary texture
    I've slightly modified the script to save the file into the same directory as the source file.

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using UnityEditor;
    4. using System.IO;
    5.  
    6. public class ExportSlicedTexture : EditorWindow
    7. {
    8.     private Texture2D texture;
    9.  
    10.     [MenuItem("Window/Export Sliced Texture")]
    11.     public static void ShowWindow()
    12.     {
    13.         GetWindow<ExportSlicedTexture>("Export Sliced Texture");
    14.     }
    15.  
    16.     private void OnGUI()
    17.     {
    18.         texture = (Texture2D)EditorGUILayout.ObjectField(texture, typeof(Texture2D), allowSceneObjects: false);
    19.         if (GUILayout.Button("Generate Sliced Image") && texture != null)
    20.         {
    21.             SaveTextureAsPNG(texture);
    22.         }
    23.     }
    24.  
    25.     public static void SaveTextureAsPNG(Texture2D texture)
    26.     {
    27.         byte[] _bytes = texture.EncodeToPNG();
    28.  
    29.         var assetPath = AssetDatabase.GetAssetPath(texture);
    30.         var assetFileInfo = new FileInfo(assetPath);
    31.         var assetDirectory = assetFileInfo.Directory.FullName;
    32.         var fileName = assetFileInfo.Name;
    33.  
    34.         var filePath = Path.Combine(assetDirectory, fileName + "_sliced.png");
    35.  
    36.         File.WriteAllBytes(filePath, _bytes);
    37.         Debug.Log(_bytes.Length / 1024 + "Kb was saved as: " + filePath);
    38.     }
    39. }
    40.  
     
    Last edited: Sep 23, 2022
    Xiangting_Su likes this.
  10. Xiangting_Su

    Xiangting_Su

    Unity Technologies

    Joined:
    Sep 22, 2020
    Posts:
    253
    Super, thanks @RequiemOfTheSun , that's super helpful!
    For anyone who weren't able to export the sliced Texture or run the function, just remember to do the 2nd step first to enable Read/Write in the PSD Importer Inspector which is under the Advanced header.

    The compression settings step seems optional (but a good step) can be found under the Platform Settings header.

    And in the Export Sliced Texture window, make sure to drag in the sliced/mosaic Texture (from the PSD Model Prefab) and not the individual Sprites themselves.
     
    Last edited: Oct 10, 2022
  11. mul118

    mul118

    Joined:
    Jul 4, 2017
    Posts:
    1
    Thank you all for your hard work!

    @Xiangting_Su and Unity devs - this seems to me like a critical gap in psd importer functionality. If 1) the PSD importer generates its own sprite sheet, and 2) any secondary textures are NOT covered by the auto-generation, the secondary texture feature is useless by default.

    I appreciate Requiem selflessly pioneering & sharing the workflow, but... having struggled with this for weeks, and having to choose either the many png + nice secondary texture route or the psd + no lighting info route for a core asset workflow, I am left wishing this critical bug in the default psd import path was fixed.
     
    Xiangting_Su and KaveeM2007 like this.
  12. Xiangting_Su

    Xiangting_Su

    Unity Technologies

    Joined:
    Sep 22, 2020
    Posts:
    253
    Thank you @mul118 and all for your helpful feedback!

    I agree that this is a worthy issue and I've brought these back to the team. I've also added all the above details into our Product Board so that we may consider them as a whole when we relook into the end-to-end secondary textures workflow.
     
    Imaginesto likes this.
  13. Imaginesto

    Imaginesto

    Joined:
    Apr 15, 2020
    Posts:
    9
    Very Interested to know if they made any progress on this workflow?
     
  14. sam_nau

    sam_nau

    Joined:
    Oct 26, 2013
    Posts:
    9
    So trying to obtain the generated sprite sheet may not be needed at all. This video offers some more built in solutions for secondary textures and normal maps with the PSD Importer.

    The basic idea is that you create a clone of your layered file with your art converted to normal maps, in the exact arrangement as the original character PSB and import it separately into your project. Disable the character rig option on the importer for this new PSB to get a normal map sprite sheet to use as a secondary texture and apply it to your character rig sprite sheet.
     
    petrknedlik3 likes this.
  15. Ivan_Draga

    Ivan_Draga

    Joined:
    May 19, 2021
    Posts:
    1
    Try this name

    upload_2024-2-29_4-45-36.png upload_2024-2-29_4-45-57.png upload_2024-2-29_4-46-15.png upload_2024-2-29_4-51-49.png