Search Unity

Bug SpriteMetaData/TextureImporter Potential Bug in Unity 2021.2.16f1

Discussion in 'Scripting' started by _GTC_, Mar 28, 2022.

  1. _GTC_

    _GTC_

    Joined:
    Mar 20, 2016
    Posts:
    8
    In order to process a huge number of sprite sheets, I use a script to do the 2D sprite sheet slicing job.

    The script I am using is derived from this post and this, and I found that most of the other automatic sprite sheet slicing solutions are more or less similar to these - create a TextureImporter, create a list of SpriteMetaData for each of the sub-sprites to slice and assign the list of SpriteMetaData to the TexttureImporter and write to asset database in the end.

    My script looks like:
    Code (CSharp):
    1. public class NPCSpriteSheetSlicer : MonoBehaviour {
    2.  
    3.     [SerializeField] private int sliceWidth = 96;
    4.     [SerializeField] private int sliceHeight = 104;
    5.     [SerializeField] private Texture2D spriteSheetToSlice;
    6.  
    7.     [Button("Slice Sprite Sheet")]
    8.     private void SliceSpriteSheet() {
    9.         string spriteSheetPath = AssetDatabase.GetAssetPath(spriteSheetToSlice);
    10.         TextureImporter customImporter = AssetImporter.GetAtPath(spriteSheetPath) as TextureImporter;
    11.         customImporter.isReadable = true;
    12.         customImporter.textureType = TextureImporterType.Sprite;
    13.         customImporter.spriteImportMode = SpriteImportMode.Multiple;
    14.         customImporter.spritePixelsPerUnit = 32;
    15.         customImporter.filterMode = FilterMode.Point;
    16.         customImporter.textureCompression = TextureImporterCompression.Uncompressed;
    17.  
    18.         Rect[] rects = InternalSpriteUtility.GenerateGridSpriteRectangles(spriteSheetToSlice, Vector2.zero, new Vector2(sliceWidth, sliceHeight), Vector2.zero);
    19.         List<SpriteMetaData> newData = new List<SpriteMetaData>();
    20.         for (int i = 0; i < rects.Length; i++) {
    21.             SpriteMetaData smd = new SpriteMetaData();
    22.             smd.rect = rects[i];
    23.             smd.alignment = (int) SpriteAlignment.Custom;
    24.             smd.pivot = new Vector2(0.5f, 0.1f);
    25.             smd.name = spriteSheetToSlice.name + "_" + i;
    26.             newData.Add(smd);
    27.         }
    28.  
    29.         customImporter.spritesheet = newData.ToArray();
    30.         AssetDatabase.ImportAsset(spriteSheetPath, ImportAssetOptions.ForceUpdate);
    31.         AssetDatabase.Refresh();
    32.     }
    33.  
    34. }
    Where you can see I have generated an array of Rect and assign it to each sub-sprite in the for loop at line 22.

    My script works perfectly fine with Unity2019.4.30.

    However, after updating my project to use Unity2021.2.16f1, the script stops working as expected.

    Previously, after the script slicing, the rect for each sub-sprite is correctly assigned, if you open the sprite sheet through sprite editor, you can click and check if the pivot point is correct (basically the same behaviour as if you manually slice the sprite through sprite editor):

    CorrectSpriteRect.png
    (here I just click on the fourth sub-sprite and the rect moves to the fourth sprite and shows e.g. where the pivot point is)

    However after updating to Unity 2021.2.16f1, if I open the sprite sheet through sprite editor after script slicing, it looks like this:

    ErrorSpriteRect.png

    Where there is only 1 rect created for the first sub-sprite.

    After some investigating, I've found something fishy in the sub-sprite meta data:
    For the same sprite sheet, here is a comparison of manually slicing the sprite (on the left) v.s. script slicing (on the right):

    meta-comparison-1.PNG
    meta-comparison-2.PNG
    meta-comparison-3.PNG

    It appears that the sub sprites all have
    spriteID 
    and
    internalID
    set to zeros and later in the
    nameFieldIdTable
    , the sub-sprites are referencing to ID 0 (which could be recognised as the first sub-sprite's ID?) and hence the odd incorrect rect assignment.
     
    Last edited: Mar 28, 2022
    sabojako and IggyZuk like this.
  2. _GTC_

    _GTC_

    Joined:
    Mar 20, 2016
    Posts:
    8
    In Unity 2019.4.30, the sprite meta data looks like this after script slicing where each sub-sprite get assign with an unique
    spriteID 
    and
    internalID
    , and get referenced correctly in the
    internalIDToNameTable
    :

    unity-2019-meta-1.PNG
    unity-2019-meta-2.PNG
     
  3. _GTC_

    _GTC_

    Joined:
    Mar 20, 2016
    Posts:
    8
    For the incorrect rect assignment after script slicing in Unity 2021.2.16f1, If I edit the sprite meta and manually assign them a unique ID and update the nameFileIdTable with these IDs, it works again:
    manually-update-meta-1.png
    manually-update-meta-2.png
    manually-update-meta-3.png

    Now there are 6 rects and I can click on each of the sub-sprite to check the pivot point.
     
  4. _GTC_

    _GTC_

    Joined:
    Mar 20, 2016
    Posts:
    8
    If I use the sprites (created by script slicing in Unity2021.2.16f1, with zero spriteID and interalID) in my Sprite Library Asset, it will cause weird issue:
    ResultingIncorrectSpriteLibraryAsset-1.png
    Here I assign the sub-sprites to a category in a Sprite Library Asset.

    ResultingIncorrectSpriteLibraryAsset-2.png
    If I use this Sprite Library Asset for a game object, the first sprite always appears as broken.
     
  5. IggyZuk

    IggyZuk

    Joined:
    Jan 17, 2015
    Posts:
    43
    I have a similar issue, any news on this?
     
  6. SmoothyD

    SmoothyD

    Joined:
    Sep 29, 2014
    Posts:
    12
    Hello,


    We also have similar issues using this tool : https://github.com/talecrafter/AnimationImporter

    Since we updated Unity, everytime a different member of the project imports it after updating his git, we have a bunch of changes in sprites meta files.

    It's really game breaking as we have many broken animations and missing sprites.

    We really hope to find a fix.
     
  7. IggyZuk

    IggyZuk

    Joined:
    Jan 17, 2015
    Posts:
    43
    That's exactly what I'm doing too. The temporary solution for now is to always delete the old generated sprite before reimporting. Seems like it works fine on clean imports, and not so well additively.
     
  8. Quasimodem

    Quasimodem

    Joined:
    May 21, 2013
    Posts:
    53
    Can you elaborate on what you mean by "delete the old generated sprite"? Do you mean to delete the texture file or .meta file from the disk? Or to use the TextureImporter.spritesheet property to set the list of sprites contained within the texture to an empty list?

    I'm not having any luck with any of the approaches mentioned in this thread and would like to find a workaround for this issue. Thanks!
     
  9. Jerkins

    Jerkins

    Joined:
    Jul 15, 2016
    Posts:
    7
    해결되었나요?
    git을 사용하는 동안에도 계속 문제가 발생합니다.
     
  10. RedHillbilly

    RedHillbilly

    Joined:
    Mar 24, 2014
    Posts:
    39
    I have the same error, not exactly sure how to solve it, but I'm looking into it.

    https://github.com/talecrafter/AnimationImporter/issues/58

    If anybody has an idea where this could come from to give a hint where to look this would be awesome!

    Cheers
     
  11. tuntorius

    tuntorius

    Joined:
    Jul 31, 2013
    Posts:
    3
    I just found out that the spritesheet property of TextureImporter is obsolete since Unity 2021.2:
    https://docs.unity3d.com/2022.2/Documentation/ScriptReference/TextureImporter-spritesheet.html
    Note that it's OBSOLETE, not DEPRECATED, which means it won't work at all. It's a crime that the property hasn't been marked to display a warning about that, or removed entirely. Just like you, I wasted a few months trying to figure out what went wrong.

    Now you need to use the Sprite Editor Data Provider API. There are links with more info in this issue:
    https://issuetracker.unity3d.com/is...ot-spritesheet-to-split-an-image-into-sprites
     
    GigaAshley, waishan and RedHillbilly like this.