Search Unity

Working with Vector Graphics - Alternatives to SVG Importer

Discussion in '2D' started by nensl, Apr 22, 2017.

  1. nensl

    nensl

    Joined:
    May 30, 2016
    Posts:
    6
    I'm looking for a way to import and work with vector graphics.
    I was thinking about buying SVG Importer but after reading some reviews from this year it looks like they don't support it properly anymore and the tool seems to have its flaws.

    So my question is if those of you working with vector graphics can recommend some plugin worth spending money for.

    Really appreciating any help :)
     
    technofeeliak likes this.
  2. YanivAvrahami

    YanivAvrahami

    Joined:
    Jun 26, 2016
    Posts:
    51
    I bought SVG 2 month ago and I asked Unity to give me my money back because SVG has lots of bugs.
    I don't know about alternatives, no one has made any thing like that, even Unity doesn't provide vector graphics. So I think the only way is to leave Unity and program your own game engine.
     
  3. Andrii

    Andrii

    Joined:
    Sep 23, 2013
    Posts:
    136
    I saw an extension that can import SVG files called RageTools. But it was last updated in 2015.

    Another option would be to use a tool that allows to create vector-like graphics inside of Unity. I'm working on an extension like this: ProtoShape 2D. It doesn't have as much options and flexibility as dedicated vector editors though but I plan to keep adding them.
     
    JoeStrout likes this.
  4. DrackoveliaDev

    DrackoveliaDev

    Joined:
    Dec 30, 2016
    Posts:
    1
  5. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    That's silly. If you can program an entire game engine, you can program your own SVG importer for Unity with about 1/1000th as much effort.
     
  6. technofeeliak

    technofeeliak

    Joined:
    Oct 2, 2017
    Posts:
    22
    I'm looking for c# code that allows the user to draw their own SVG dynamically.
    In ActionScript 3.0 it was simple.
    I was able to create all my 8 bit vector graphics with code.
    I think c# would nee me to create an array of coordinates first, then put them into the instructions to draw a shape.
    It's never easy getting information. I'll never understand why it's so hard to get decent references.

    private var lever_0_0_0:Sprite = new Sprite();
    private var _lever_0_0_0:Graphics = lever_0_0_0.graphics;

    this.addChild(lever_0_0_0);

    _lever_0_0_0.beginFill(0x000000, 1);
    _lever_0_0_0.moveTo(13, 1);
    _lever_0_0_0.lineTo(13, 3);
    _lever_0_0_0.lineTo(15, 3);
    _lever_0_0_0.lineTo(15, 8);
    _lever_0_0_0.lineTo(13, 8);
    _lever_0_0_0.lineTo(13, 10);
    _lever_0_0_0.lineTo(14, 10);
    _lever_0_0_0.lineTo(14, 1);
    _lever_0_0_0.endFill();
     
  7. technofeeliak

    technofeeliak

    Joined:
    Oct 2, 2017
    Posts:
    22
  8. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    You seem to be confusing some concepts. It's not "ActionScript 3.0" that made it simple to create vector graphics with code, it was Flash. Because it was made to do that. ActionScript is simply a language used to program Flash and use a vector drawing API. Likewise, C# is a language, not a graphics API, and a generic C# book will not help. You would need an underlying engine or library to do that, and the language isn't relevant.

    Unity does have their own SVG package which works with Unity 2018 and later, which can import SVG files or create vector graphics on the fly with code. There's some information about the API in the Unity docs.

    --Eric
     
  9. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Thanks for pointing this out; I knew about the new SVG import, but hadn't realized it came with a nice dynamic API. Cool stuff.
     
  10. technofeeliak

    technofeeliak

    Joined:
    Oct 2, 2017
    Posts:
    22
    Yes, it took banging my head against a wall (figuratively) for a few days to realize that Unity uses meshes made with triangles rather than scalable vector graphics. I would have to learn a lot more about creating my own class to add this functionality to Unity. But I think I can manage to create meshes with coordinates almost the same way I would create an SVG. Now, I wonder if there's an easy way to get the vertices of a mesh as a list from a mesh I import into Unity.
    What I'm actually trying to do is create these meshes dynamically. I don't know enough about Unity, but through trial and error I did figure out that my Flash game would benefit from quicker processing speeds when I wrote code to represent the sprites rather than count on external vector files. I'm not sure I'm making myself clear, but if you think you understand my meaning and you have a solution to offer then please do. :)
     
  11. technofeeliak

    technofeeliak

    Joined:
    Oct 2, 2017
    Posts:
    22
    Okay, this is all still new to me... but I'm exploring my options. I already appreciate how easy Unity is to use, and the response time of the community in answering my questions. The quicker I can understand what I need to do the sooner I'll have games out for everyone to enjoy.
    I really need this, so I can leave the town I reside in and start my life without having to worry about government support.
     
  12. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    ...Why not just use the Unity vector functions I referenced in my previous post? There's a link and everything.

    --Eric
     
    technofeeliak likes this.
  13. technofeeliak

    technofeeliak

    Joined:
    Oct 2, 2017
    Posts:
    22
    Well, from what I understand this class is very limited. I don't actually need to animate the sprites using a rig. But I'm worried that I won't be able to animate using a series of frames. This is all new to me, I'm exploring my options currently. I don't want to spend months researching and trying things like I had to in Flash with ActionScript 3.0.
     
  14. technofeeliak

    technofeeliak

    Joined:
    Oct 2, 2017
    Posts:
    22
  15. technofeeliak

    technofeeliak

    Joined:
    Oct 2, 2017
    Posts:
    22
    upload_2019-5-21_17-20-57.png
    Okay Eric, I'm taking your advice. Thank you sir.
     
  16. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    It sounds to me like you may enjoy 2D Animation Methods in Unity.
     
    technofeeliak likes this.
  17. technofeeliak

    technofeeliak

    Joined:
    Oct 2, 2017
    Posts:
    22
    I always find that learning to write in a new language is an ordeal.
    So, I have to ask now, how do I interpret this information?
    I would like to write what's necessary to draw my Super Mario sprite dynamically (as a test don't get excited - copyright).
    I've found a way to extract the vertices coordinates from my original svg file.
    When I try to make a simple Bézier or line I try creating an array like they show here in the example but it won't take integers and it won't accept floats.
    Should I maybe create variables of some kind? What am I doing wrong?

    upload_2019-5-21_19-51-37.png

    upload_2019-5-21_19-50-38.png
     
  18. RichardKain

    RichardKain

    Joined:
    Oct 1, 2012
    Posts:
    1,261
    Well, if you're looking to use SVG graphics to create pixels, you're probably doing it wrong. It's entirely possible to take this approach, but it is also kind of a waste. The benefit of using Vector-based graphics is in making smooth, scale-able graphics with clean, smooth lines. Low-resolution pixel-based graphics fly in the face of this.

    To be honest, you would probably be better off trying to "convert" these graphics into basic 3D models. Polygons are not as expensive as they used to be, and most "vector" drawing in Unity really boils down to 3D models anyway. It would even be possible to optimize them somewhat to take up the lowest possible number of polygons. This isn't exactly the typical approach for these kinds of graphics, but it would work, and it would provide certain advantages.
     
    technofeeliak likes this.
  19. technofeeliak

    technofeeliak

    Joined:
    Oct 2, 2017
    Posts:
    22
    Thank you RicharKain,

    But you see, I really would like to create these images dynamically.
    When I import an svg file I have to break it up into 3 different files. It's just so complicated for nothing.
    And I have used Blender to make these vector graphics into 3D meshes as a test but I'm not satisfied with that.
    I want to take the coding approach. So please, how do I interpret the API reference where drawing a simple vector shape is concerned?
    I found a way to do this in the past writing in ActionScript 3.0.
    The structure made sense to me. I don't understand how this works in C#. What elements do I need to setup?
    - using Unity.VectorGraphics;
    - an array...
    - something to a shape with...
    I was expecting these instructions to be straight forward. Why the mystery?
    Cause I don't enjoy melting my brain like a grilled cheese sandwich.

    upload_2019-5-21_20-22-27.png upload_2019-5-21_20-21-25.png
     
  20. technofeeliak

    technofeeliak

    Joined:
    Oct 2, 2017
    Posts:
    22
    Or how does one go about tesselating a scene when creating vector graphics?
    Isn't there a simple guide?
    Why is coding in Unity a secret?
    I can throw graphics into the program, they'll work well enough. But I'm not interested in taking this approach because laziness is not my goal.
    What I want is control. That's why I need to write this rather than just use the simple U.I..
     
  21. technofeeliak

    technofeeliak

    Joined:
    Oct 2, 2017
    Posts:
    22
    Listen, I would really appreciate it if you would explain how one goes about writing the code to draw a shape.
    I checked your links, and there is information there but I don't know how to actually apply it in a practical way.
    So, would you be really nice and just spell it out for me please? Just pretend I'm a dummy.
    I wasn't born knowing C# or how to code so it's not helpful if I'm just shown how the abstract class looks with no way of knowing how to implement it in my own code. So, what do I do with this?
    Draw a line? Fill it... you know?


    upload_2019-5-21_22-13-45.png
     
  22. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    I don't know what that means.

    Probably because it's something very few people have wanted to do. If you use something in the usual way, you find lots of guides on how to do that. If you want to do something weird, you'll probably have to figure it out on your own.

    This is laughable. There are thousands of tutorials about coding in Unity, in both written and video form. In addition to that there is an official manual and a scripting reference, each of which would be a thick book if printed in book form, and which provide everything you need to know about coding in Unity if you take the time to read it.

    In short, now you're just whining.

    I still can't work out what the heck it is you're trying to write/control. If you whine less and focus on asking clear questions more, you'll more quickly get the answers you need.
     
  23. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    If by "one" you mean "most people," then the standard way is (1) throw a PNG program into your project, (2) check the import settings to make sure its type is set to "Sprite", and then (3) drag it from the Project tab to the Hierarchy tab (which automatically creates a GameObject with a SpriteRenderer component and hooks it up for you).

    I'm not kidding. This is the standard way. Vector graphics are a brand-new feature, which I can't advise you on because I haven't used it — nor have most other people. If you want to blaze trails, crack open the books and start studying. If you want an easy solution handed to you, then quit trying to blaze trails and just do things the standard way.

    You've mentioned "tesselation" a few times, which maybe hints that you're trying to dynamically create a mesh. In that case I recommend this tutorial series at Catlike Coding, which walks you through the process. It's also not something most people ever need to do, but it is a much older capability than the new SVG stuff, and so the tiny fraction of people who ever need to do it have had time to master it and put out some tutorials.
     
    technofeeliak likes this.
  24. RichardKain

    RichardKain

    Joined:
    Oct 1, 2012
    Posts:
    1,261
    The mesh you made in Blender actually looks pretty good. How familiar are you with Python? Blender has its own Python API that allows you to do all sorts of operations, including loading files and generating meshes. You might consider writing an import script for Blender that converts imported SVG graphics into a 3D mesh. (or trying to find an existing similar plug-in that someone else has written)
     
    technofeeliak likes this.
  25. technofeeliak

    technofeeliak

    Joined:
    Oct 2, 2017
    Posts:
    22
    Thanks Joe,
    and yes I do realize I'm giving myself a real headache for nothing. I bet no one would ever care that I'd use png files. But it's the kind of thing that keeps me up at night, makes me hate myself and say I wish I had never been born. Okay, seriously though I just want the smallest file size and the most efficient game along with really smooth graphics. I may make a simple version with meshes I create in Blender to start with, but I've recently discovered that Unity can import .svg files. It requires a little plug in that's available under Window>Package Manager... click on Advanced and type in Vector into the search area to get what is displayed here. I think it's a bit confusing though, for anyone who thinks that Unity can handle SVG the way Illustrator does. I believe it actually transforms these vector graphics into meshes. I think I'm going to look into Richard's suggestion to see if Blender can give me the script to create a mesh dynamically. But I'm not expert, I'm somewhat of a noob. Cue Franck Sinatra's song... "High Hopes".

    upload_2019-5-23_0-29-21.png
     
  26. technofeeliak

    technofeeliak

    Joined:
    Oct 2, 2017
    Posts:
    22
    I went through a lot to recreate these graphics as svg in Adobe Illustrator only to trace them with a little program I created in ActionScript 3.0 that would trace/Debug.log all of the Cartesian coordinates. Took me months... decided to abandon Flash... and here I am. My own personal hell ;)

    thanks guys.

    Mario-Maker-Ui-Animation.gif
     
  27. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Yes, Unity can now use SVG files, and it does indeed convert them to meshes under the hood, but you shouldn't care about that. Meshes are what video cards draw; everything (even text) gets converted to meshes under the hood, and that's just how the machines work. Particularly as a beginner, this an implementation detail you shouldn't worry about.

    But the graphics you're showing are pixel graphics. They are inherently not vector-y. Yes, you can trace them out and convert them to SVG, but this is (to be blunt) a dumb thing to do. It makes bigger, less efficient files. The most efficient (compact and speedy) way to represent a pixel image, is as a pixel image (i.e. a PNG file).
     
  28. RichardKain

    RichardKain

    Joined:
    Oct 1, 2012
    Posts:
    1,261
    I found out yesterday that Blender already features the ability to import SVG graphics, and can convert them to 3D meshes natively. So you won't need to write any scripts, the current version of Blender should allow you to import the vector graphics right out of the box.
     
  29. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Unity also imports SVG graphics natively. But I still don't see the point in this case.
     
  30. RichardKain

    RichardKain

    Joined:
    Oct 1, 2012
    Posts:
    1,261
    Well, with a 3D mesh, you wouldn't have to worry about alpha-channel testing in your material, and you wouldn't have to worry about Unity generating a dynamic mesh to conform to your low-resolution pixel graphics. Also, with a saved mesh you would be able to effectively scale and rotate your sprites with ease, without any worries about rendering. Changing the colors of your characters and tiles would also be easier. (just swap out a pre-defined material)

    It's not a traditional approach. But I think it could be an interesting experiment. In particular, I would like to see some performance testing on how well a game could handle that load of polygons.

    For low-resolution games it could work fairly well. Where I see it breaking down a little bit is when you start scaling up to higher resolutions. Using 3D models as a substitute for pixels wouldn't work nearly as well at a 1080p target resolution. The more complex the pixel art, the more onerous such an approach would be. (and the less sense it would make)
     
    Last edited: May 23, 2019
    JoeStrout likes this.
  31. technofeeliak

    technofeeliak

    Joined:
    Oct 2, 2017
    Posts:
    22
    Hey guys!
    So I've been recreating this graphic manually with code. I want to leave a link to the video that helped me do this.
     
  32. technofeeliak

    technofeeliak

    Joined:
    Oct 2, 2017
    Posts:
    22
    It doesn't look like much but let me assure you this represents a couple hours of work.
    I'll be creating a tool to handle the rest of the graphics that's for sure. It's taken some steps too for the planning side.

    With this code you get a free hat and overalls. Don't say I never gave you anything lol.

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    [RequireComponent(typeof(MeshFilter))]
    public class MeshGenerator : MonoBehaviour
    {
    Mesh thisMesh;

    Vector3[] vertices;
    int[] triangles;

    void Start()
    {
    thisMesh = new Mesh();
    GetComponent<MeshFilter>().mesh = thisMesh;

    CreateShape();
    UpdateMesh();
    }

    void CreateShape()
    {
    //We're going to define vertices here in an array
    vertices = new Vector3[]
    {
    //each number is a point on the x,y,z axes
    //0 is the center of your scene
    //hat
    new Vector3(-4,6,0),
    new Vector3(-4,7,0),
    new Vector3(-3,7,0),
    new Vector3(-3,8,0),
    new Vector3(2,8,0),
    new Vector3(2,7,0),
    new Vector3(5,7,0),
    new Vector3(5,6,0),
    //pants
    new Vector3(-4, -6, 0),
    new Vector3(-4 ,-4 ,0),
    new Vector3(-3, -4, 0),
    new Vector3(-1, -6, 0),
    new Vector3(-1, -5, 0),
    new Vector3(-2, -3, 0),
    new Vector3(-3, -2, 0),
    new Vector3(-2, -2 ,0),
    new Vector3(-1, -3, 0),
    new Vector3(-2, 1, 0),
    new Vector3(-1, -1, 0),
    new Vector3(-1, 1, 0),
    new Vector3(-1, -2, 0),
    new Vector3(1, -1, 0),
    new Vector3(1, -2, 0),
    new Vector3(1, -3, 0),
    new Vector3(1, -5, 0),
    new Vector3(1 ,0 ,0),
    new Vector3(2, 0, 0),
    new Vector3(2, -2, 0),
    new Vector3(2, -3, 0),
    new Vector3(3, -2, 0),
    new Vector3(3, -4, 0),
    new Vector3(4, -4, 0),
    new Vector3(4, -6, 0),
    new Vector3(1, -6, 0)

    };

    //this is an array that creates the triangle referring to the verticies array's index
    triangles = new int[]
    {
    0, 1, 2,
    2, 4, 5,
    0, 2, 5,
    2, 3, 4,
    0, 5, 7,
    5, 6, 7,

    8, 9, 10,
    8, 10, 11,
    10, 12, 11,
    10, 13, 12,
    10, 14, 13,
    14, 15, 13,
    13, 16, 12,
    15, 17, 18,
    17, 19, 18,
    15, 18, 20,
    20, 18, 21,
    20, 21, 22,
    16, 20, 22,
    16, 22, 23,
    12, 16, 23,
    12, 23, 24,

    21, 25, 26,
    21, 26, 27,
    22, 21, 27,
    28, 27, 29,
    28, 29, 30,
    24, 23, 28,
    24, 28, 30,
    33, 24, 30,
    33, 30, 32,
    30, 31, 32

    };
    }
    void UpdateMesh()
    {
    //this will clear any previous information inside the Mesh
    thisMesh.Clear();

    //input our vertex and triangle arrays
    thisMesh.vertices = vertices;
    thisMesh.triangles = triangles;

    thisMesh.RecalculateNormals();

    }
    }



    upload_2019-5-25_23-45-42.png

    upload_2019-5-25_23-44-53.png
     
  33. technofeeliak

    technofeeliak

    Joined:
    Oct 2, 2017
    Posts:
    22
    Okay, I didn't complete the tool I was creating in Flash and ActionScript 3.0.
    I found a way to extract the mesh data from the MeshFilter component.
    What was blocking my access was a simple unchecked checkbox.
    The box in question was buried in the inspector.
    I had to click on the asset in the project window... the one I wanted to extract the data from...
    In the inspector, under the Model tab there's a checkbox that was made available "Read/Write Enabled".
    Checking gave me access to the data... that's mesh.vertices and mesh.triangles.
    Then I added my script to the mesh in the Hierarchy on the left. That made a link possible to the MeshFilter, from which I could get the data.
    If anyone is interested, you'll find my video helpful along with the code I copied and pasted in the comments.
     
    Last edited: Jun 22, 2019
  34. technofeeliak

    technofeeliak

    Joined:
    Oct 2, 2017
    Posts:
    22
    I've taken it a step further today...
    Here's the code that actually works.
    It takes the data from the mesh, turns it into a string and formats it too.


    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    public class GetVerticesAndTriangles : MonoBehaviour
    {
    [SerializeField] private MeshFilter meshFilter;
    [SerializeField] private Mesh mesh;
    [SerializeField] private Vector3[] vertices;
    [SerializeField] private int[] triangles;
    public string output;

    private void Start()
    {
    mesh = GetComponent<MeshFilter>().mesh;

    for (var i = 0; i < mesh.vertices.Length; i++)
    {
    //vertices[0] = vertices[0] * 2;
    }

    vertices = mesh.vertices;
    triangles = mesh.triangles;
    createOutput();
    createOutput2();
    updateTheMesh();
    }
    private void createOutput()
    {
    output += "using System.Collections;" + "\n" + "using System.Collections.Generic;" + "\n" + "using UnityEngine;" + "\n" + "\n";
    output += "[RequireComponent(typeof(MeshFilter))] " + "\n";
    output += "public class MeshGenerator : MonoBehaviour" + "\n" +"{" + "\n";
    output += "\t" + "Mesh mesh;" + "\n" + "\t" + "Vector3[] vertices;" + "\n" + "\t" + "int[] triangles;" + "\n" + "\n" + "\t" + "// Use this for initialization" + "\n" + "\t" + "void Start()" + "\n" + "\t" + "{" + "\n" + "\t" + "\t" + "mesh = new Mesh();" + "\n" + "\t" + "\t" + "GetComponent<MeshFilter>().mesh = mesh;" + "\n" + "\t" + "\t" + "CreateShape();" + "\n" + "\t" + "\t" + "UpdateMesh(); " + "\n" + "\t" + "}" + "\n";
    output += "\t" + "void CreateShape()" + "\n" + "\t" + "{" + "\n";
    output += "\t" + "\t" + "vertices = new Vector3[]" + "\n" + "\t" + "\t" + "{";
    for (var i = 0; i < vertices.Length; i++)
    {
    output += "\n" + "\t" + "\t" + "\t" + "new Vector3 (" + ((float)vertices[0]).ToString() + "f, " + ((float)vertices[1]).ToString() + "f, " + ((float)vertices[2]).ToString() + "f),";
    //Debug.Log(vertices[0]);
    }
    output += "\n" + "\t" + "\t" + "};";
    }
    private void createOutput2()
    {
    output += "\n" + "\t" + "\t" + "triangles = new int[]" + "\n" + "\t" + "\t" + "{";

    int lineSep = 0;

    for (var i = 0; i < triangles.Length; i++)
    {
    if (lineSep == 0)
    {
    output += "\n" + "\t" + "\t" + "\t";
    }
    lineSep++;
    if (lineSep > 2)
    {
    lineSep = 0;
    }
    output += triangles + ", ";
    }
    output += "\n" + "\t" + "\t" + "};" + "\n" + "\t"+ "}";
    }
    private void updateTheMesh()
    {
    output += "\n" + "\t" + "void UpdateMesh()" + "\n" + "\t" + "{" + "\n" + "\t" + "\t" + "mesh.Clear();" + "\n" + "\t" + "\t" + "mesh.vertices = vertices;" + "\n" + "\t" + "\t" + "mesh.triangles = triangles;" + "\n" + "\t" + "}";
    output += "\n" + "}";
    }

    }
     
  35. technofeeliak

    technofeeliak

    Joined:
    Oct 2, 2017
    Posts:
    22
    I was able to figure out how to scale my 3D meshes in Blender to get them to be the right dimensions for Unity. And in Unity I set it not to change to Unity units (very important). The beauty of all of this, besides not having to load external files is just how simple the animation process will be. I have 3 meshes, one for each color. I can make any shape I want and it's still 3D. I'm not claiming to be an expert. It's been a little over a month since I began using Unity. We'll see where this goes right?
     
  36. technofeeliak

    technofeeliak

    Joined:
    Oct 2, 2017
    Posts:
    22
    Okay, if the benefits of turning meshes into code (mesh verts coordinates (Vector3[]) array and triangles (int[]) array then look at how easy it is to expand these bushes.