Search Unity

  1. Are you interested in providing feedback directly to Unity teams? Sign up to become a member of Unity Pulse, our new product feedback and research community.
    Dismiss Notice

Unity UI SVG support script

Discussion in '2D Experimental Preview' started by phil-Unity, Sep 5, 2018.

  1. amcagurban

    amcagurban

    Joined:
    Dec 12, 2018
    Posts:
    12
    upload_2019-1-24_17-24-31.png
    Oh, I use RectMask2D in my game and it works without any problem. Don't you use RectMask2D?
    Anyway, hope you'll solve your problem asap :)
    Bu arada kral Türk müsün? Üstteki postta attığın resmin adı 'Ekran Resmi'
     
  2. hitwill

    hitwill

    Joined:
    Jun 5, 2016
    Posts:
    10
    Once I have imported an SVG, how do I change the fill of a path through code? (or even get a reference to the SVG?) I can't find any documentation.
     
  3. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    725
    The way to do this would be to parse the SVG file to get a vector representation of the file (vector Scene), then you can change any properties before tessellation. For example:

    Code (CSharp):
    1. string svg =
    2.     @"<svg xmlns=""http://www.w3.org/2000/svg"" xmlns:xlink=""http://www.w3.org/1999/xlink"" viewBox=""0 0 216 216"">
    3.        <g>
    4.            <polygon id=""Poly1"" points=""...""/>
    5.        </g>
    6.    </svg>";
    7.  
    8. // Import the SVG at runtime
    9. var sceneInfo = SVGParser.ImportSVG(new StringReader(svg));
    10. var shape = sceneInfo.NodeIDs["Poly1"].Shapes[0];
    11. shape.Fill = new SolidFill() { Color = Color.red };
    12.  
    13. // Tessellate
    14. var geoms = VectorUtils.TessellateScene(sceneInfo.Scene, tessOptions);
    15.  
    16. // Build a sprite
    17. var sprite = VectorUtils.BuildSprite(geoms, 10.0f, VectorUtils.Alignment.Center, Vector2.zero, 128, true);
    18. GetComponent<SpriteRenderer>().sprite = sprite;
    19.  
    You can have a look here for a more complete example:
    https://github.com/Unity-Technologi...b/master/Assets/RuntimeDemo/SVGRuntimeLoad.cs
     
    Arkade and hitwill like this.
  4. hitwill

    hitwill

    Joined:
    Jun 5, 2016
    Posts:
    10
    This is GREAT! I have been looking for sample code for a couple of days but couldn't find the link. Thanks!

    One question - is it possible to apply the generated sprite to a 3d object, like a cube? Would the sprite go into the material for the cube? What would be the best way? (A high level response would be great, then I can just do the code myself)
     
  5. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    725
    I assume you want to apply it like a texture? Given that vector sprites are essentially triangle meshes, you won't be able to UV map it to a 3D object as-is. Instead, you could convert the vector sprite to a texture, then apply it to the object.

    You can either import the SVG asset as a "textured sprite", or convert it programmatically using the VectorUtils.RenderSpriteToTexture2D method.
     
  6. hitwill

    hitwill

    Joined:
    Jun 5, 2016
    Posts:
    10
    Thanks! I will try this. I had added a Sprite Renderer as a child of the object I wanted the sprite to appear on - and this seemed to work fine. However, is this a wasteful way of doing it, or perhaps a bit hacky?

    I am a decent coder, but new to Unity and 3D - so still trying to figure out the best practices.
     
  7. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    725
    It depends if you want the SVG sprite to be "attached" to the 3D object, or if you really want to the SVG sprite to deform and wrap around the 3D object. Your solution is fine for the former, but I think you need a texture for the latter.
     
  8. hitwill

    hitwill

    Joined:
    Jun 5, 2016
    Posts:
    10
    Great! I just wanted it to attach on the surface, and actually not wrap around! Fatastic!!
     
  9. haywirephoenix

    haywirephoenix

    Joined:
    May 17, 2017
    Posts:
    93
    Is it possible to add the 360 radial fill setting to the inspector? I haven't been able to extend the class to add this.
     
  10. dyawitz

    dyawitz

    Joined:
    Aug 22, 2017
    Posts:
    5
    Has the SVG support for UI elements been rolled out to a Unity release yet, or still in development? Thanks.
     
  11. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    725
    If I understand correctly, you want to control the radial gradient from the SVG importer inspector? This is not possible, the gradient data is read from the SVG file itself.
     
  12. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    725
    Not yet, we're working on it.
     
  13. dyawitz

    dyawitz

    Joined:
    Aug 22, 2017
    Posts:
    5
    Then what am I seeing here in 2018.3.12 that, after adding the Vector Graphics package, I have SVG image as an option under UI to add to a canvas? Thanks.
     

    Attached Files:

    • SVG.PNG
      SVG.PNG
      File size:
      35.5 KB
      Views:
      702
  14. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    725
    Ah, I thought you were referring to UIElements support: https://blogs.unity3d.com/2019/04/16/introducing-unity-2019-1/#uielements

    The SVG support for the UI canvas is part of the vector graphics package, not part of Unity.
     
    TeotiGraphix likes this.
  15. dyawitz

    dyawitz

    Joined:
    Aug 22, 2017
    Posts:
    5
  16. haywirephoenix

    haywirephoenix

    Joined:
    May 17, 2017
    Posts:
    93
    Thanks for your reply. I was actually talking about the fill options in unity. The radial option allows you to do a circular progress bar. I wanted to add this feature to the vector version of UI Image
     
  17. haywirephoenix

    haywirephoenix

    Joined:
    May 17, 2017
    Posts:
    93

    Like this:
     

    Attached Files:

  18. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    725
    Oh, sorry for the misunderstanding. The radial filling is done by manipulating the sprite's "quad" and its UVs, so this won't work for SVG sprites since these aren't textured (unless you import them as "Textured Sprites" instead of "Vector Sprites").
     
  19. haywirephoenix

    haywirephoenix

    Joined:
    May 17, 2017
    Posts:
    93
    Ah, that makes sense. That could be why I couldn't get it to work! Thank you. Maybe I can do something with masking.

    Edit: Masking works perfectly
     
    Last edited: May 1, 2019
  20. TeotiGraphix

    TeotiGraphix

    Joined:
    Jan 11, 2011
    Posts:
    145
    Just filing in for notifications but I am starting to use this vector package for a pretty large app so we will see how it goes.

    Thanks for all your work on this mcoted3d.
     
    mcoted3d likes this.
  21. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    717
    @mcoted3d When will the "Keep Aspect Ratio" be implemented? As it should be an easy feature...
    Someone already implemented it but changing it in a package will only keep those changes locally in the Library folder I think. Link

    Also creating a material that uses the Unlit/Vector or Unlit/VectorGradient, the canvas will complain in SendWillRenderCanvases method that the material does not have a _Stencil property.
     
  22. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    725
    You can absolutely use the script that you referenced. Drop it in your Assets folder (you may have to change the class name to avoid conflicts) and you're good to go. I don't know when this will be pushed as part of the package.

    Thanks for reporting!
     
  23. jason_yak

    jason_yak

    Joined:
    Aug 25, 2016
    Posts:
    406
    Hey just chiming in so I can follow along with this thread. Looking forward to seeing the ui support for SVG out of preview. Is there any roadmap available for the SVG plugin with features and unity version breakdown? we found the roadmap that the LWRP team did was super handy for us to plan out what tech solutions, thanks.
     
  24. jason_yak

    jason_yak

    Joined:
    Aug 25, 2016
    Posts:
    406
    ^ haha nevermind.. I just saw your post in the main SVG thread that said there's no roadmap. No worries =)
     
    mcoted3d likes this.
  25. gromilQaaaa

    gromilQaaaa

    Joined:
    Oct 28, 2013
    Posts:
    14
    Hello, I am trying to change the property of a material in runtime. But there is no .sharedMaterial in SVGImage so I guess .material works as shared. Didn't find any normal way to change property of direct material instance. Help :)
     
  26. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    725
    This should work. I tried with this code snippet:

    Code (CSharp):
    1.         var mat = GetComponent<SVGImage>().material;
    2.         mat.color = Color.gray;
    3.  
    What's not working on your side?
     
  27. gbriozzo

    gbriozzo

    Joined:
    Sep 7, 2018
    Posts:
    2
    Hello! I am having a problem with RectMask2D when the material is Unlit/VectorGradient, I have implemented a zoom system and when the material is empty the image is correctly contained in the edges of the mask, but when assigning Unlit / VectorGradient it is not properly contained
    attaching screen caps
    Is this a bug or intended behaviour?
    Thanks in advance
     

    Attached Files:

  28. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    725
    This looks like a bug. Can you open a case for this please? (Help > Report a Bug...)
     
    gbriozzo likes this.
  29. tbg10101_

    tbg10101_

    Joined:
    Mar 13, 2011
    Posts:
    172
    I'm trying out the UI SVGImage component. Is there any way to enable MSAA just for the UI to help the edges?
     
  30. tbg10101_

    tbg10101_

    Joined:
    Mar 13, 2011
    Posts:
    172
    Answering my own question:
    • Create a new camera
      • Configure the camera only render UI objects
      • Configure the camera to clear using a transparent color
      • Have the camera render to a RenderTexture
      • Configure the RenderTexture to use MSAA
      • Add an image effect to your original camera that overlays the RenderTexture
    • Switch the canvas to 'Screen Space - Camera'
      • Assign the new camera
    When I set MSAA to 8x my edges look pretty again and it is only applied to the UI!

    (disclaimer: only works for render pipelines which support camera stacking)
     
    Last edited: Nov 7, 2019
    sirxeno and mcoted3d like this.
  31. tristanlbailey

    tristanlbailey

    Joined:
    Jul 14, 2016
    Posts:
    12
  32. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    725
    "use" is supported, but it requires the "xlink:href" attributes. The example in the mozilla doc works when specified as such:

    Code (CSharp):
    1. <svg viewBox="0 0 30 10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    2.   <circle id="myCircle" cx="5" cy="5" r="4" stroke="blue"/>
    3.   <use xlink:href="#myCircle" x="10" fill="blue"/>
    4.   <use xlink:href="#myCircle" x="20" fill="white" stroke="red"/>
    5. </svg>
     
    tristanlbailey likes this.
  33. Chris-Trueman

    Chris-Trueman

    Joined:
    Oct 10, 2014
    Posts:
    1,020
    I have a concern about Stroke.

    I am trying to get consistency between rectangles and circles. Right now I set both of them to have the same HalfThickness. Yet they both show different size strokes.

    VectorStrokeProblem.png

    Both are setup identically, only one is a circle and the other a rectangle. I created them using the VectorUtils Make functions.
     
  34. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    725
    This is odd, I have a hard time to explain this.

    If there's a different scale transform on one of the elements, that could explain it. Otherwise, can you share the code that generates these shapes?
     
  35. Chris-Trueman

    Chris-Trueman

    Joined:
    Oct 10, 2014
    Posts:
    1,020
    I neglected the fact that I added [SerializeField] in my base class to the field that controls that value. I had made the circle class first and made some adjustments. Created the rectangle class, was pretty tired and forgot about adjusting the stroke in the circle class. I kept looking at the base class thinking they are both the same value.

    Sorry for taking your time.
     
  36. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    725
    No worries, glad you figured it out.
     
  37. Korindian

    Korindian

    Joined:
    Jun 25, 2013
    Posts:
    575
    How is the antialiasing for Overlay canvases coming for Unity UI? With the roadmap session today, I see that Unity has a high interest in using SVGs with UI Toolkit. Just hoping that Unity has antialiasing for all canvas modes in mind for the UI Toolkit as well.
     
  38. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    725
    Yes, absolutely. And this is a feature we're very excited about!
     
    Korindian likes this.
  39. Janko_O

    Janko_O

    Joined:
    May 21, 2019
    Posts:
    6
    Hello,

    Is it possible to get the nested svg by id?
    Like in the code below (I've edited the code posted earlier):

    Code (CSharp):
    1.     string svg =
    2.         @"<svg xmlns=""http://www.w3.org/2000/svg"" xmlns:xlink=""http://www.w3.org/1999/xlink"" viewBox=""0 0 216 216"">
    3.           <svg id =""a""></svg>
    4.           <svg id =""b""></svg>
    5.       </svg>";
    6.    
    7.     // Import the SVG at runtime
    8.     var sceneInfo = SVGParser.ImportSVG(new StringReader(svg));
    9.     var shape = sceneInfo.NodeIDs["a"].Shapes[0];
    10.  
    I can't get it working...
     
  40. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    725
    We don't support nested <svg> tags. If you can get away with a <g> tag instead, that should work.
     
  41. Rafarel

    Rafarel

    Joined:
    Jul 21, 2017
    Posts:
    198
    Hello there!

    I'm building my game UI at a 4k resolution with PNG sprites.
    Some of the sprites renders very bad when playing in Full HD, especially the outlined ones.
    So I wanted to investigate the possibilities of using SVG for my UI like I do when I'm building a website.
    I wonder what are the best practices to get a neat UI in both 4K and Full HD resolutions?

    upload_2020-5-30_19-39-25.png


    I downloaded the VectorGraphics preview.12 - 2.0.0 but I don't understand how I can use a SVG image in my UI canvas.
    I don't know how to set the import and how to add this image on my canvas ?
    Is there any guide to learn this workflow?
    Is there any repository where I can download a component to add vector graphics to UI ?

    Thanks for your help!
     
  42. Janko_O

    Janko_O

    Joined:
    May 21, 2019
    Posts:
    6
    Once you've added the VectorGraphics package into your project, Unity should be able to correctly see SVG files (if they are in your Assets folder). Then you can click on the SVG file in Unity and convert it to Sprites or similar.
    I think you can also do it via script (examples above in the post), but this one's simpler in the editor.
     
    Rafarel likes this.
  43. Rafarel

    Rafarel

    Joined:
    Jul 21, 2017
    Posts:
    198
    Hello @Janko44 and thanks for your answer.

    I found a new object on the UI menu when I right click on the canvas in the Hierarchy.

    It's called SVG Images, so I made some tests with it but my icons are still ugly in small sizes
    It's working very well on bize sizes.

    I found an old topic on Reddit that advice to turn on mipmaps on my icons, and for now this is the best results I've got by far, it is with High res PNGs with mipmap enabled.

    https://www.reddit.com/r/Unity3D/comments/7066oc/best_practice_for_clean_unity_canvas_ui/

    The original icon has been designed in 256*256 resolution, and here is a comparison of SVG (top) and PNG with mipmaps (64*64 to 2048*2048 resize test on a 4K canvas)

    upload_2020-5-31_17-44-11.png
     
  44. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    725
    This is an aliasing issue. If you can, configure your canvas in "camera overlay" mode, and enable antialiasing on the camera (Edit > Project Settings > Quality > Anti-Aliasing). The SVG package currently rely on MSAA for antialiasing.
     
  45. Rafarel

    Rafarel

    Joined:
    Jul 21, 2017
    Posts:
    198
    Hi @mcoted3d and thank you for your answer !
    This looks much better with the 8x anti aliasing on.
    I guess that the MSAA requires more client side performances.

    I know that I can have a camera just for my UI, so that I can have one using MSAA and not the other one ?
    Mhhh sounds that MSAA if for the whole project, oh wait I can disable it on the game camera, but what if I want to different MSAA settings ? Like 2x for game and 8x for UI ?

    I tried the two camera setup but without success, my whole game end up to be black and I just see my UI.

    Here is my game Camera where I removed UI from culling mask :
    upload_2020-6-3_18-40-36.png

    Here is my UI camera :
    upload_2020-6-3_18-41-34.png

    Here is my Canvas
    upload_2020-6-3_18-50-49.png

    And here is the result ...

    upload_2020-6-3_18-34-26.png

    Any idea of what I'm doing wrong ?
    Thanks a lot for your help!
     
    Last edited: Jun 3, 2020
  46. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    725
    MSAA will require more memory for the backing render target. The memory requirements increases linearly with the number of samples (8x MSAA requires a render target 8x larger). In most cases, 4x MSAA is a good compromise between quality/memory requirements.

    The rendering performances should not be significantly affected by MSAA, since it is optimized to only execute the fragment shader once per pixel, regardless of the number of samples.

    Yes. The way to do this is usually to render the UI in a RenderTexture with the number of samples that you want, then compose the UI RenderTexture over the scene (this can be done with a simple quad mesh attached to the main camera).

    However, doing that will require even more memory, since both cameras will require separate render targets. My recommendation would be to use a single camera with MSAA enabled.
     
    Rafarel likes this.
  47. Rafarel

    Rafarel

    Joined:
    Jul 21, 2017
    Posts:
    198
    Hi @mcoted3d , thank you very much for your answer!

    I have another thing that is specific to my game.
    I use additive scenes. I have a Game scene for the game and its UI, and I have a Menu scene for the menus that is always loaded because it is used both in game and on the main menu.
    My question is how do you tell the Menu scene canvas wich camera to use ?
    Maybe my additive scene strategy is bad, what do you recommend ?

    upload_2020-6-4_18-23-32.png

    Many thanks! Have a nice day :)
     
  48. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    725
    If you set your canvas in "Camera Space - Overlay" render mode, you'll be able to set the rendering camera.
     
  49. Rafarel

    Rafarel

    Joined:
    Jul 21, 2017
    Posts:
    198
    @mcoted3d For now I have to main scenes Home & Game.
    Every time a stack of scenes are loaded in additive mode :

    Bootstrap + Main + Home + Menu
    OR
    Bootstrap + Main + Game + Menu

    Home and Game has their own camera (Game use a ProCamera2D that Home do not need).
    So how I tell to the Menu scene canvas to use the camera located either in Home or Game scene ?
     
  50. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    725
unityunity