Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

bugs/issues in Unity 4.3 Sprite implementation

Discussion in '2D' started by brianchasalow, Dec 9, 2013.

  1. brianchasalow

    brianchasalow

    Joined:
    Jun 3, 2010
    Posts:
    208
    So I finally got around to playing with Unity 4.3's 2D Sprites, really just to try to take advantage of the built-in atlas generation/packing. I came across a few performance and usage issues.
    My webplayer demo is live at www.chasalow.com, and github src link is on that page too.

    Bug 1) unsure if this is a bug per se… but sprites appear to be somewhat inefficient in draw call usage when rendered via SpriteRenderer.
    I really would like to draw 1 big mesh and use the Sprite's auto packing/texture sheet. Is that the most efficient way to efficiently draw sprites- do it myself by using sprite.textureRect et. al?

    Here's two examples: in both examples, I have 860 64x64 Sprites, auto-arranged on 2 sprite sheets by a packing tag.
    example1: my test scene has 10,800(120x90 grid) of SpriteRenderers, all drawing the same sprite repeatedly in a grid. it batches 10768, and requires 32 drawcalls. is this because every 337.5 sprites requires its own mesh? Some clarification (esp. in the documentation) about sprite batching specifics might be nice.
    example2: my test scene has 10,800(120x90 grid) of SpriteRenderers, each drawing a (potentially) unique sprite. I end up with 1600 or more drawcalls. It is batching something like 9000 calls. Is this expected?

    Bug 2) using the resources folder prevents sprite packing- but the only way to access the Sprite in an editor script (from what I can tell) is from the Resources folder by doing
    Sprite[] sprites = Resources.LoadAll<Sprite>("myImagesFolder");
    and
    Texture2D tex = UnityEditor.Sprites.DataUtility.GetSpriteTexture(sprites, false);

    Sprites being in the Resources folder _prevents sprite packing entirely_, it would appear. You can't have both editor script access to your Sprite objects, and actual sprite packing, simultaneously.

    Bug 3) sprite.texture doesn't work, and accessing the sprite's texture using the above (undocumented) editor function is a pain.

    Will submit some bugs in the morning, bed now.
     
  2. TomasJ

    TomasJ

    Joined:
    Sep 26, 2010
    Posts:
    256
    Hi, thanks for the feedback.

    1) Will require a repro case for this. It is possible that you have some sprites from one atlas and some from another - texture swapping kills batching.
    2) Atlasing is disabled for the Resources folder in 4.3 by design. You can use http://docs.unity3d.com/Documentation/ScriptReference/AssetDatabase.LoadAllAssetsAtPath.html to access sprites imported from a texture.
    3) sprite.texture should work unless the texture has been deleted.
     
  3. brianchasalow

    brianchasalow

    Joined:
    Jun 3, 2010
    Posts:
    208
    Tomas: sorry for the misfire- #3 works as of 4.3.1. maybe I was using an earlier version when i tested last night.

    As for #2, I'm simply trying to be able to select the Sprites in the editor, from an editor script. It doesn't need to be the Resources folder, but that's the only place I was successfully able to load the assets. I.e., this returns zero:

    Object[] obj = AssetDatabase.LoadAllAssetsAtPath("myFolder");
    Debug.Log ("object count:" + obj.Length);
    this doesn't work either:
    Object[] obj = Selection.GetFiltered(typeof(Sprite), SelectionMode.Deep);
    but this does:
    Sprite[] textures = Resources.LoadAll<Sprite>("otherSprites");

    I'll submit a repro for #1.
     
  4. TomasJ

    TomasJ

    Joined:
    Sep 26, 2010
    Posts:
    256
    AssetDatabase.LoadAllAssetsAtPath takes in a file name, not a folder name. Give it a path to the texture you're generating sprites from.
     
  5. brianchasalow

    brianchasalow

    Joined:
    Jun 3, 2010
    Posts:
    208
    oh. that makes some sense. so I need to use the File class and iterate through each file in the folder, and LoadAllAssetsAtPath on each file. How come Selection isn't working, though? I imagine that would be useful.

    I imagine some of this confusion/difficulty stems from the fact that the actual sprites are children of the texture importer in the project view, even though the sprite has a .texture property. that seems somewhat counterintuitive, and I've seen other posts where people have been similarly confused about how to access the 'texture's sprite' as opposed to the 'sprite's texture' -- I don't have any suggestions for how to alleviate that confusion other than better documentation on it, though.
     
  6. brianchasalow

    brianchasalow

    Joined:
    Jun 3, 2010
    Posts:
    208
    BTW, (for other people's reference)- this works:
    Code (csharp):
    1.  
    2.         string myDir = "/myFolder";
    3.         DirectoryInfo dir = new DirectoryInfo(Application.dataPath + myDir);
    4.         if(!dir.Exists){
    5.             Debug.Log ("no folder!");
    6.             return;
    7.         }
    8.         List<System.IO.FileInfo> info = new List<System.IO.FileInfo>();
    9.         //load supported file types here
    10.         info.AddRange(dir.GetFiles("*.png", System.IO.SearchOption.TopDirectoryOnly));
    11.         info.AddRange(dir.GetFiles("*.gif", System.IO.SearchOption.TopDirectoryOnly));
    12.         info.AddRange(dir.GetFiles("*.jpg", System.IO.SearchOption.TopDirectoryOnly));
    13.  
    14.         if(info != null){
    15.             string[] paths = new string[info.Count];
    16.             for(int i = 0 ; i < info.Count; i++){
    17.                 paths[i] = info[i].FullName.ToString();
    18.                 Debug.Log ("got a proper path: " + paths[i]);
    19.                 Sprite sprite = AssetDatabase.LoadAssetAtPath("Assets" + myDir + "/" + Path.GetFileName(paths[i]), typeof(Sprite)) as Sprite;
    20.                 Debug.Log ("Sprite: " + sprite.name + " " + sprite.textureRect );
    21.                 //access the sprite's texture here at sprite.texture
    22.             }
    23.         }
    24.