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.
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): using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; public class ExportSlicedTexture : EditorWindow { private Texture2D texture; private string name; [MenuItem("Window/Export Sliced Texture")] public static void ShowWindow() { GetWindow<ExportSlicedTexture>("Export Sliced Texture"); } private void OnGUI() { texture = (Texture2D)EditorGUILayout.ObjectField(texture, typeof(Texture2D), allowSceneObjects: false); name = EditorGUILayout.TextField("File name: ", name); if (GUILayout.Button("Run Function") && texture != null) { SaveTextureAsPNG(texture, name); } } public static void SaveTextureAsPNG(Texture2D texture, string fileName) { byte[] _bytes = texture.EncodeToPNG(); var dirPath = Application.dataPath + "/Sprite Sheets/"; if (!System.IO.Directory.Exists(dirPath)) { System.IO.Directory.CreateDirectory(dirPath); } System.IO.File.WriteAllBytes(dirPath + fileName + ".png", _bytes); Debug.Log(_bytes.Length / 1024 + "Kb was saved as: " + fileName + ".png"); } }
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.
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?
Thanks for this, but I found it didn't work in my case after following instructions. The script threw errors: Code (CSharp): Unsupported texture format - Texture2D::EncodeTo functions do not support compressed texture formats. UnityEngine.ImageConversion:EncodeToPNG(Texture2D) ExportSlicedTexture:SaveTextureAsPNG(Texture2D, String) (at Assets/Editor/ExportSlicedTexture.cs:28) ExportSlicedTexture:OnGUI() (at Assets/Editor/ExportSlicedTexture.cs:22) UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr) NullReferenceException: Object reference not set to an instance of an object System.IO.File.WriteAllBytes (System.String path, System.Byte[] bytes) (at <437ba245d8404784b9fbab9b439ac908>:0) ExportSlicedTexture.SaveTextureAsPNG (UnityEngine.Texture2D texture, System.String fileName) (at Assets/Editor/ExportSlicedTexture.cs:34) ExportSlicedTexture.OnGUI () (at Assets/Editor/ExportSlicedTexture.cs:22) 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) Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation. [...] 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!
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.
Oh that's great news! 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?
This thread really helped me out. My process was: Set Compression to 'None' Make the sprite 'Read/Write Enabled' Drag the Split image from the PSD/PSB import children into the script tool window Generate sliced image Create normal map from sliced image (tool 'Sprite Illuminator') 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): using UnityEngine; using UnityEditor; using System.IO; public class ExportSlicedTexture : EditorWindow { private Texture2D texture; [MenuItem("Window/Export Sliced Texture")] public static void ShowWindow() { GetWindow<ExportSlicedTexture>("Export Sliced Texture"); } private void OnGUI() { texture = (Texture2D)EditorGUILayout.ObjectField(texture, typeof(Texture2D), allowSceneObjects: false); if (GUILayout.Button("Generate Sliced Image") && texture != null) { SaveTextureAsPNG(texture); } } public static void SaveTextureAsPNG(Texture2D texture) { byte[] _bytes = texture.EncodeToPNG(); var assetPath = AssetDatabase.GetAssetPath(texture); var assetFileInfo = new FileInfo(assetPath); var assetDirectory = assetFileInfo.Directory.FullName; var fileName = assetFileInfo.Name; var filePath = Path.Combine(assetDirectory, fileName + "_sliced.png"); File.WriteAllBytes(filePath, _bytes); Debug.Log(_bytes.Length / 1024 + "Kb was saved as: " + filePath); } }
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.
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.
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.
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.