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

Sprite rendering problem (maybe misplaced UV)

Discussion in '2D' started by turbo3d, Nov 19, 2014.

  1. turbo3d

    turbo3d

    Joined:
    Apr 28, 2014
    Posts:
    50
    I'm working on an Editor script for SVGAssets that, given:
    • a pow2 texture (512 x 256) asset, that is just for editor purposes, because it will be generated from an SVG text asset at runtime (i.e. just once initialization time) on the device:
    • a set of sprite assets built from the texture:
    • a scene where the sprites have been instantiated and positioned to form an orc character:
    it should produce a build (BuildPipeline.BuildPlayer) such that it must not contain the whole 512 x 256 texture, but instead a dummy 1x1 texture, preserving all the sprite instances --> sprites --> texture linking.
    Proceeding with the following operations, in this exact order:

    1. modify each sprite asset "resizing" its texture rectangle to a 1x1 pixel region, located in (0, 0)
      Code (CSharp):
      1.  
      2. // SpriteData is a custom class containing the Sprite plus addition related information (e.g. name, pivot, rect)
      3. foreach (SpriteData spriteData in generatedSpritesAssets)
      4. {
      5.     Sprite original = spriteData.sprite;
      6.     // we must reference the original texture, because we want to keep the file reference (rd->texture.IsValid())
      7.     Sprite tmpSprite = Sprite.Create(original.texture, new Rect(0, 0, 1, 1), new Vector2(0, 0), SVGAtlas.SPRITE_PIXELS_PER_UNIT);
      8.     // now we change the (sprite) asset content: actually we have just reduced its rectangle to a 1x1 pixel
      9.     EditorUtility.CopySerialized(tmpSprite, original);
      10. }
      11.  
    2. substitute texture asset content (i.e. pixels) with a 1x1 texture (backuping the original one)

      Code (CSharp):
      1.  
      2. // TextureBuildInfo is a custom class that maintains a (deep) copy of a given texture
      3. public class TextureBuildInfo
      4. {
      5.     public TextureBuildInfo(int width, int height, Color32[] srcPixels)
      6.     {
      7.        this.Width = width;
      8.        this.Height = height;
      9.        this.Pixels = new Color32[width * height];
      10.        System.Array.Copy(srcPixels, this.Pixels, srcPixels.Length);
      11.     }
      12.     public int Width;
      13.     public int Height;
      14.     public Color32[] Pixels;
      15. }
      16. // generate a 1x1 texture
      17. Texture2D tmpTexture = new Texture2D(1, 1, TextureFormat.ARGB32, false);
      18. // list of textures clones
      19. List<TextureBuildInfo> texturesClones = new List<TextureBuildInfo>();
      20. // clone each generated texture
      21. foreach (Texture2D original in generatedTexturesAssets)
      22. {
      23.     TextureBuildInfo clone = new TextureBuildInfo(original.width, original.height, original.GetPixels32());
      24.      texturesClones.Add(clone);
      25.      // copy the 1x1 texture inside the original texture
      26.      EditorUtility.CopySerialized(tmpTexture, original);
      27. }
      28.  
    3. produce the build
      Code (CSharp):
      1.  
      2. // save modified assets (textures and sprites)
      3. AssetDatabase.SaveAssets();
      4. // build the player
      5. BuildPipeline.BuildPlayer(null, "C:\\Temp\\unity_build", BuildTarget.StandaloneWindows, BuildOptions.None);
      6.  
    4. restore the texture content
      Code (CSharp):
      1.  
      2. for (i = 0; i < generatedTexturesAssets.Count; i++)
      3. {
      4.      Texture2D original = generatedTexturesAssets[i];
      5.      TextureBuildInfo clone = texturesClones[i];
      6.      Texture2D cloneTex = new Texture2D(clone.Width, clone.Height, TextureFormat.ARGB32, false);
      7.      cloneTex.SetPixels32(clone.Pixels);
      8.      // restore the original texture
      9.      EditorUtility.CopySerialized(cloneTex, original);
      10. }
      11.  
    5. restore sprites
      Code (CSharp):
      1.  
      2. foreach (SpriteData spriteData in generatedSpritesAssets)
      3. {
      4.     Sprite original = spriteData.sprite;
      5.     Sprite tmpSprite = Sprite.Create(original.texture, spriteData.rect, spriteData.pivot, SVGAtlas.SPRITE_PIXELS_PER_UNIT);
      6.     // restore the original sprite
      7.     EditorUtility.CopySerialized(tmpSprite, original);
      8.     original.name = spriteData.name;
      9. }
      10.  
    6. update asset database
      Code (CSharp):
      1.  
      2. AssetDatabase.SaveAssets();
      3.  
    It seems that all is performed correctly:
    • the buildPlayer is working as expected (it contains the 1x1 texture generating the right one at runtime)
    • the texture asset is restored correctly (within the editor and in the Asset folder)
    • the sprites assets are restored correctly (serialized sprite file assets looks identical: texture link is ok, vertices/uv are the same)
    • the editor console does not display errors
    but at the end of the script, the scene looks weird and wrong:


    What could cause these glitches?
    After closing and reopening the Unity editor, the scene and all the sprites looks good again.
    Note that, after closing the Unity editor, assets files have not been changed.
    I've tried both OpenGL and DirectX10 backends, Unity 4.5.5 on Windows 7.
     
    Last edited: Nov 19, 2014
  2. Ska0s

    Ska0s

    Joined:
    Feb 4, 2014
    Posts:
    32
    no one?
     
  3. lgarczyn

    lgarczyn

    Joined:
    Nov 23, 2014
    Posts:
    68
    A complete shot in the dark, but it looks like you managed to mess with the vertex texture coordinates. Not even sure you can manually set those in Unity, but if you can, it should be easy to fix your problem.
     
  4. NemoKrad

    NemoKrad

    Joined:
    Jan 16, 2014
    Posts:
    632
    Not looked at your code in any detail yet, but as to what ceandros said above, to check this can you show them with wireframe on, we can then see how the sprite it scaled then too..
     
    turbo3d likes this.