Batch setting secondary textures in Unity Sprite editor


 Unity 2019.2 introduced new feature for adding secondary textures in Sprite editor. If you want to use it in your current project with lot of sprites, it can result into tedious manual work. In this tutorial I will show simple script, that can do all the hard work for you.

Adding secondary sprite texture manually

 First, let’s see how to add secondary texture manually. We will add normal texture for existing sprite.
 Open Sprite Editor from texture importer in inspector. In top left drop-down choose Secondary Textures as shown on image below. Now, in right-bottom corner, you can add secondary sprite textures. Each entry has Name and Texture.
 Name has to be equal to name your shader understands. By default, you can choose _NormalMap or _MaskTex. These two names are used by Sprite-Lit-Default shader which is available if you installed Lightwave Rendering Pipeline with 2D renderer. You can use any other name your custom shader understands (I will write another tutorial on how to use emissive textures later).
 Texture is reference to asset with 2D texture. Simply, drag and drop it here. In our example we are using normal texture for character sprite.

Adding secondary sprite textures in batch with script

 As mentioned in the beginning, if you have lot of sprites and want to add secondary textures, it can be boring manual work. Fortunately, it is easy to write editor script, that will do it for you.
 This script expects all textures with normals to be placed in subfolder of any name. Name of each normal texture should append “_n” in the end like this: ” original_sprite_name_n.png”, so script knows what to look for (by the way, this is default naming if you use SpriteIlluminator). This is simple structure for two sprites of chest – I named subfolder with normals as … Normals!

 Here comes the script. To use it, select all sprites you want to process in project window. Then go into My Tools menu and choose “Add secondary texture to sprite”. When it finishes processing, you should have normal maps attached.

using UnityEngine;
using UnityEditor;
using System.IO;

public class SpriteTools {

    public static readonly string NORMAL_MAP_SUFFIX = "_n";
    public static readonly string SECONDARY_TEXTURE_NAME_NORMAL = "_NormalMap";

    // -----------------------------------------------------------
    [MenuItem("My Tools/Add secondary texture to sprite")]
    public static void AddSecondaryTextureToSprite() {

        // filter selection to assets only
        Object[] spriteAssets = Selection.GetFiltered(typeof(Object), SelectionMode.Assets);

        // process all assets
        foreach (Object item in spriteAssets) {

            // path to selected sprite asset
            string spriteAssetPath = AssetDatabase.GetAssetPath(item);


            // find normal texture in subfolders
            string normalTextureName = Path.GetFileNameWithoutExtension(spriteAssetPath) + NORMAL_MAP_SUFFIX;
            string normalTextureType = " t:Texture2D";
            string[] searchFolders = AssetDatabase.GetSubFolders(Path.GetDirectoryName(spriteAssetPath));
            string[] normalGUIDs = AssetDatabase.FindAssets(normalTextureName + normalTextureType, searchFolders);

            // if no normal, then log warrning
            if (normalGUIDs == null || normalGUIDs.Length == 0) {
                Debug.LogWarning("Not found " + normalTextureName + " in subfolders");
                continue;
            }


            // get texture importer for current sprite asset
            TextureImporter importer = AssetImporter.GetAtPath(spriteAssetPath) as TextureImporter;

            // create secondary texture entries array
            SecondarySpriteTexture[] secondarySpriteTextures = new SecondarySpriteTexture[] {
                new SecondarySpriteTexture {
                    name = SECONDARY_TEXTURE_NAME_NORMAL,
                    texture = AssetDatabase.LoadAssetAtPath<Texture2D>(AssetDatabase.GUIDToAssetPath(normalGUIDs[0]))
                }
            };
            // set new array to importer
            importer.secondarySpriteTextures = secondarySpriteTextures;


            // save importer
            EditorUtility.SetDirty(importer);
            importer.SaveAndReimport();
        }
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *