I’ve been trying to write a quick script to rename sprite slices without breaking references to the sprites in sprite renderers or animations. I thought it would be simple since you can do this manually through the Sprite Editor without any issues, but I have run into a difficult snag.
The script I currently have seems to work fine, except that my references break (“Missing Sprite”).
I’ve tried using different methods for importing the asset, as I find that pretty unclear from the Unity documentation. I’ve used both AssetImporter.SaveAndReimport (), and AssetDatabase.ReimportAsset (path, ImportAssetOptions.ForceUpdate), (both seeming to require calling EditorUtility.SetDirty() on my import settings), but both have the same results.
In examining the meta files before and after my script, I see the renamed file has a few references to the old files in the “fileIDToRecycleName” section, and I’m wondering if that might be the issue. For example:
Original file:
fileIDToRecycleName:
21300000: UI_Buttons_0
21300002: UI_Buttons_1
21300004: UI_Buttons_2
21300006: UI_Buttons_3
Renamed File:
fileIDToRecycleName:
21300000: UI_Buttons_0
21300002: UI_Buttons_1
21300004: UI_Buttons_2
21300006: UI_Buttons_3
21300008: RenamedSprite_0
21300010: RenamedSprite_1
21300012: RenamedSprite_2
21300014: RenamedSprite_3
If I rename the slices manually they will keep the original fileID.
Has anyone solved this issue? Can anyone tell me how to rewrite Texture Import Settings on slices without regenerating their meta data?
Code:
using UnityEngine;
using UnityEditor;
public class SpritesheetRename : MonoBehaviour
{
[MenuItem ("Assets/Rename Spritesheet")]
public static void RenameSpritesheet ()
{
RenameSelectedTexture ();
}
static void RenameSelectedTexture ()
{
// Validation
var selectedObject = Selection.activeObject;
if (!AssetDatabase.Contains (selectedObject)) {
Debug.LogError ("Selected object not found in Asset Database.");
return;
}
string path = AssetDatabase.GetAssetPath (selectedObject);
var importer = AssetImporter.GetAtPath (path) as TextureImporter;
if (importer == null) {
Debug.LogError ("Selected object not found in Asset Database.");
return;
}
// Rename the slices
SpriteMetaData[] spritesheet = importer.spritesheet;
bool textureHasSpritesheet = spritesheet != null && spritesheet.Length > 0;
if (textureHasSpritesheet)
{
for (int i = 0; i < spritesheet.Length; i++) {
spritesheet*.name = "RenamedSprite_" + i;*
-
}*
-
importer.spritesheet = spritesheet;*
-
// Reimport the asset*
-
EditorUtility.SetDirty (importer); // Flag dirty for SaveAndReimport to find it*
-
importer.SaveAndReimport ();*
-
// Don't need to do this since settings were already reimported via SaveAndReimport*
-
//AssetDatabase.ImportAsset (path, ImportAssetOptions.ForceUpdate);*
-
}*
-
// TODO: Rename the asset as well once slice renaming is working*
-
//AssetDatabase.RenameAsset (path, "Renamed.png");*
-
//AssetDatabase.Refresh ();*
-
}*
-
[MenuItem (“Assets/Rename Spritesheet”, true)]*
-
public static bool IsValidTargetForPalette ()*
-
{*
-
if (Selection.activeObject == null) {*
-
return false;*
-
}*
-
if (Selection.objects.Length > 1) {*
-
return false;*
-
}*
-
return Selection.activeObject.GetType () == typeof(Texture2D);*
-
}*
}
I’ve based my script off of similar questions I’ve found here:
- Editor script to slice sprites - Questions & Answers - Unity Discussions
- http://answers.unity3d.com/questions/753664/