How to change individual spritesheet in TextureImporter object without regenerating all spriteIDs

In the TextureImporter’s SetSpriteRects implementation, we do not write the data back to the Name/FileId map, so the data stored in the Sprite Rects vs. the data stored in the Name/FileId map will diverge if you skip the SetFileIdPairs-call. This means that if there is a contention for either the name or an ID, whatever is stored in the Name/FileId map will win over what’s stored in a Sprite Rect, which in turn will most likely lead to a broken reference.

I see, thank you for the confirmation! Not sure what was updating the pairs then, but I’ll be sure to make the SetNameFileIdPairs call to be safe. Thanks @Ted_Wikman

On that note… I’ve been working on a utility to copy over sprite rect data from one Texture2D to another (hence why I’ve been interested in this thread). In my first implementation, I was quite literally taking the SpriteRects and the FileID pairs from texture A, and using the dataproviders to set the rects and pairs on texture B.

This means that texture A and B would have identical Name - FileId pairs in their metafiles. So my question is: is there any circumstance that could be problem down the road? Or otherwise is this considered bad practice?

Obviously texture A and texture B have different GUIDs themselves, so if one object was making a reference to texture A’s sprite 1, it would look different than if were referencing texture B’s sprite 1 (even though both sprite 1’s have the same FileId):

fileID: , guid:
fileID: , guid:

I’ve since changed my code for this utility to create brand new SpriteRect objects that copy the corresponding SpriteRects from Texture A’s data, but then they generate different spriteID and internalIDs (which I also make sure that the new corresponding FileIdPair has the same ID). Is this better practice? Or is it unnecessary since the two texture assets have different GUIDs anyways?

Sounds like a neat tool!

The FileIds in the Name/FileId map are local to the texture and are not being used to compare across multiple textures, so copying this data over shouldn’t cause any issues.

Regarding the suggested implementation, I would go for a new ID for any copied data. The reason is that in the rare occasion that you need to debug this data, you have a smaller chance to have the same ID used for two Sprites in different textures, which makes for clearer debugging.

1 Like

I really appreciate the super quick feedback @Ted_Wikman ! That makes sense, thank you.

For posterity I’ll drop a link to my (updated) solution from another thread here:

1 Like

Nice one, thanks for sharing your solution with the community!

What kind of object do I need to pass to GetSpriteEditorDataProviderFromObject to be able to get a ISpriteNameFileIdDataProvider back from it?

I tried passing a PSDImporter object, which gives me the ISpriteEditorDataProvider just fine, but then that data provider won’t give me an ISpriteNameFileIdDataProvider.

I am guessing maybe the PSDImporter needs to implement this or I am missing something about the nature of this API.

It is up to each importer how they would like to generate and store the ids of the individual objects. PsdImporter does not make use of ISpriteNameFileIdDataProvider, since its primary use is to import layers from Photoshop. These layers have a GUID (in most cases, depending on the DCC tool creating the .psd/.psb file) which is being used to identify a layer and keep its id intact even though the name may change outside of Unity.

1 Like

That’s useful to know, thanks. For the PSDImporter I ended up using “sub-assets” and the AssetDatabase API for now.

1 Like

Sorry for the revive, but I was not able to use SetNameFileIdPairs to change the GUID of a sprite.
If I don’t set anything in the SpriteRect when I create it, and provide it in the SetNameFileIdPairs, it will do nothing and a random GUID will be provided.
When I set a GUID in the newSpriteRect.spriteID, that GUID was used.