Search Unity

Using PolygonCollider2D with the Vector Graphics package / new SVG importer

Discussion in '2D' started by bhison, Jul 17, 2018.

  1. bhison

    bhison

    Joined:
    Feb 9, 2015
    Posts:
    9
    Hello all. I've been playing with the new Vectorgraphics package which is currently in preview. I've noticed that when attaching a PolygonCollider2D, the points of the path are not set to the shape of the sprite, as is the usual behaviour. Instead it just behaves as if no sprite is on the GameObject.

    I understand that this is due to the fact that SVGs are actually rendered in quite a different way to raster images and as such the usual method of creating points probably doesn't work (whatever that function is, I'd love to know more about it!). That said, this creates a lot of overhead having to manually draw a collider for each shape used in your project, so I was wondering if I'm missing something or if there's plans to add this functionality soon?

    As a workaround, I have figured out I can export PNG versions of shapes in to a folder, generate spriterenderers with those, attach polygon colliders, then swap out the png for the SVG. If you need finer detail on the path of the collider, you can up scale the PNG, then scale it down down once the svg is swapped in.
     
    HemelPhoenix likes this.
  2. Cacal

    Cacal

    Joined:
    Jul 6, 2018
    Posts:
    4
    Hello to all as well! I'm exploring the Vector Graphics preview package right now too, and I'm also wondering if there is a functionality for this. Has there been any progress since @bhison asked this question? :)

    I apologize if I may have bumped an old question. I'm new to using Unity forums. hehe
     
    HemelPhoenix likes this.
  3. Huminaboz

    Huminaboz

    Joined:
    Mar 12, 2013
    Posts:
    6
    Would also like this feature :D
     
    HemelPhoenix likes this.
  4. mooninen

    mooninen

    Joined:
    Apr 14, 2017
    Posts:
    2
    I'd also like this feature... It feels like the svg support has been abandoned since 2018 and doesn't seem to be supported in the 2021 beta (2021.1.0b1). I had issues with the aliasing, for which I had to update the build settings, but other than that it seems to work quite well and would be a good workflow for me.
     
    HemelPhoenix likes this.
  5. sa20001

    sa20001

    Joined:
    Feb 17, 2022
    Posts:
    1
    I'm using the package Vector Graphics, Version 2.0.0-preview.21 - April 19, 2023, I extended the above mentioned workaround for my workflow. I post it in the case someone still need it.
    1. Import the SVG file in the "Assets" folder
    2. In the "Inspector" tab of the imported asset change "Generated Asset Type" to "Textured Sprite"
    3. Tick "Use SVG Pixels Per Unity"
    4. Change value of "Texture Size", "Wrap mode" etc as you see fit, then click apply
    5. Add collider to the sprite
    6. In the "Inspector" tab of the imported asset change "Generated Asset Type" to "Vector Sprite", then click appl

    Now you have an SVG asset with a working collider.

    If you have to do this operation many times and on many files (like me), here is my workflow to automate the process.

    1. On a generic SVG asset file edit the options as you see fit, set option "Generated Asset Type" to "Vector Sprite"
    2. Save these setting as a preset, let's call it "VectorSpritePreset" from now on img1.png
    3. Always on a generic SVG asset file edit the options as you see fit, set option "Generated Asset Type" to "Textured Sprite"
    4. Tick "Use SVG Pixels Per Unity", change value of "Texture Size", "Wrap mode" etc as you see fit
    5. Save these setting as a preset, let's call it "TexturedSpritePreset" from now on.
    6. Create a c# with the following code
      Code (CSharp):
      1. using UnityEngine;
      2. using UnityEditor;
      3. using System.IO;
      4. using UnityEditor.Presets;
      5. using UnityEngine.Tilemaps;
      6.  
      7. public class SVGCollider
      8. {
      9.  
      10.     public enum TypeOfCollider
      11.     {
      12.         BoxCollider,
      13.         BoxCollider2D,
      14.         CapsuleCollider,
      15.         CircleCollider2D,
      16.         CompositeCollider2D,
      17.         CustomCollider2D,
      18.         EdgeCollider2D,
      19.         MeshCollider,
      20.         PolygonCollider2D,
      21.         SphereCollider,
      22.         TerrainCollider,
      23.         TilemapCollider2D,
      24.         WheelCollider
      25.     }
      26.  
      27.     /// <summary>
      28.     /// Add a collider to an SVG asset.
      29.     /// </summary>
      30.     /// <param name="gameObject">The svg gameobject to which to add the collider</param>
      31.     /// <param name="assetFileLocation">The location of the asset</param>
      32.     /// <param name="VectorSpritePreset">The preset of the svg asset considered as a vector sprite</param>
      33.     /// <param name="TexturedSpritePreset">The preset of the svg asset considered as a textured sprite (not vectorial image)</param>
      34.     /// <param name="type">The type of the collider to add to the sprite</param>
      35.     public static void AddCollider(GameObject gameObject, string assetFileLocation, string VectorSpritePreset, string TexturedSpritePreset, TypeOfCollider type)
      36.     {
      37.        
      38.         if (!File.Exists(TexturedSpritePreset) || !File.Exists(VectorSpritePreset))
      39.         {
      40.             Debug.LogError("Missing preset files, aborting operation!");
      41.             return;
      42.         }
      43.  
      44.         if (!Path.GetExtension(assetFileLocation).Equals(".svg"))
      45.         {
      46.             Debug.LogError("Not an .svg file, aborting operation!");
      47.             return;
      48.         }
      49.  
      50.         Preset newAssetPreset = AssetDatabase.LoadAssetAtPath<Preset>(TexturedSpritePreset);
      51.         Preset oldAssetPreset = AssetDatabase.LoadAssetAtPath<Preset>(VectorSpritePreset);
      52.  
      53.         var importer = AssetImporter.GetAtPath(assetFileLocation);
      54.         if (importer != null && newAssetPreset.ApplyTo(importer))
      55.         {
      56.             AssetDatabase.WriteImportSettingsIfDirty(TexturedSpritePreset);
      57.             Debug.Log($"Preset {Path.GetFileName(TexturedSpritePreset)} applied succesfully to asset {Path.GetFileName(assetFileLocation)}");
      58.         }
      59.         else
      60.         {
      61.             Debug.LogError($"Failed to apply preset {Path.GetFileName(TexturedSpritePreset)} to asset {Path.GetFileName(assetFileLocation)}, aborting operation!");
      62.             return;
      63.         }
      64.  
      65.         AssetDatabase.ImportAsset(assetFileLocation); // reimport the asset so unity sees that I changed the preset
      66.  
      67.         switch (type)
      68.         {
      69.             case TypeOfCollider.BoxCollider: gameObject.AddComponent<BoxCollider>(); break;
      70.             case TypeOfCollider.BoxCollider2D: gameObject.AddComponent<BoxCollider2D>(); break;
      71.             case TypeOfCollider.CapsuleCollider: gameObject.AddComponent<CapsuleCollider>(); break;
      72.             case TypeOfCollider.CircleCollider2D: gameObject.AddComponent<CircleCollider2D>(); break;
      73.             case TypeOfCollider.CompositeCollider2D: gameObject.AddComponent<CompositeCollider2D>(); break;
      74.             case TypeOfCollider.CustomCollider2D: gameObject.AddComponent<CustomCollider2D>(); break;
      75.             case TypeOfCollider.EdgeCollider2D: gameObject.AddComponent<EdgeCollider2D>(); break;
      76.             case TypeOfCollider.MeshCollider: gameObject.AddComponent<MeshCollider>(); break;
      77.             case TypeOfCollider.PolygonCollider2D: gameObject.AddComponent<PolygonCollider2D>(); break;
      78.             case TypeOfCollider.SphereCollider: gameObject.AddComponent<SphereCollider>(); break;
      79.             case TypeOfCollider.TerrainCollider: gameObject.AddComponent<TerrainCollider>(); break;
      80.             case TypeOfCollider.TilemapCollider2D: gameObject.AddComponent<TilemapCollider2D>(); break;
      81.             case TypeOfCollider.WheelCollider: gameObject.AddComponent<WheelCollider>(); break;
      82.             default:
      83.                 Debug.LogError("Wrong collider!");
      84.                 break;
      85.         }
      86.  
      87.         Debug.Log($"{type} succesfully added to {gameObject.name}, reverting to preset {Path.GetFileName(VectorSpritePreset)}");
      88.         if (importer != null && oldAssetPreset.ApplyTo(importer))
      89.         {
      90.             AssetDatabase.WriteImportSettingsIfDirty(VectorSpritePreset);
      91.             Debug.Log($"Preset {Path.GetFileName(VectorSpritePreset)} applied succesfully to asset {Path.GetFileName(assetFileLocation)}");
      92.         }
      93.         else
      94.         {
      95.             Debug.LogError($"Failed to apply preset {Path.GetFileName(TexturedSpritePreset)} to asset {Path.GetFileName(assetFileLocation)}, manually update it");
      96.             return;
      97.         }
      98.  
      99.         AssetDatabase.ImportAsset(assetFileLocation); // reimport the asset so unity sees that I changed the preset
      100.     }
      101. }
    7. Call the function AddCollider() to add a collider to your svg file
    Probably it's not the best way but it works