├── Editor ├── SvgImporterEditor.cs.meta ├── SvgImporterSettings.cs.meta ├── SvgPixelDataStorage.cs.meta ├── SvgPixelDataStorage.cs ├── Artees.SVGImporter.Editor.asmdef.meta ├── SvgImporterEditor.cs ├── SvgImporter.cs.meta ├── SvgImporterWindow.cs.meta ├── Artees.SVGImporter.Editor.asmdef ├── SvgImporterSettings.cs ├── SvgImporterWindow.cs └── SvgImporter.cs ├── LICENSE.meta ├── README.md.meta ├── Editor.meta ├── package.json ├── package.jsonpackage ├── package.json.meta ├── package.jsonpackage.meta ├── README.md ├── .gitignore └── LICENSE /Editor/SvgImporterEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bd9319400da44a679eb8644d633aeb04 3 | timeCreated: 1562387654 -------------------------------------------------------------------------------- /Editor/SvgImporterSettings.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 042841902c894af5ba9ebea449846839 3 | timeCreated: 1519448951 -------------------------------------------------------------------------------- /Editor/SvgPixelDataStorage.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 00e0cd42cb3c402b84b9a684bfd2a2f7 3 | timeCreated: 1522121359 -------------------------------------------------------------------------------- /Editor/SvgPixelDataStorage.cs: -------------------------------------------------------------------------------- 1 | namespace Artees.SVGImporter.Editor 2 | { 3 | internal enum SvgPixelDataStorage 4 | { 5 | Default, 6 | Metadata, 7 | Png 8 | } 9 | } -------------------------------------------------------------------------------- /LICENSE.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f4865e119e3e9f84290da78aca2e562b 3 | timeCreated: 1495662894 4 | licenseType: Free 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 622a215a608d8e9449ee4035c6c38b8a 3 | timeCreated: 1495662894 4 | licenseType: Free 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/Artees.SVGImporter.Editor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 60ac4576e141dcd4b8e7210b8cfc6233 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Editor/SvgImporterEditor.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | 3 | namespace Artees.SVGImporter.Editor 4 | { 5 | [CustomEditor(typeof(SvgImporter)), CanEditMultipleObjects] 6 | internal class SvgImporterEditor : UnityEditor.Editor 7 | { 8 | } 9 | } -------------------------------------------------------------------------------- /Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fe1764fcb3980514abd6e54886f9b89a 3 | folderAsset: yes 4 | timeCreated: 1519199788 5 | licenseType: Pro 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Editor/SvgImporter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7af788b8580746d4586afbdd5cd7857a 3 | timeCreated: 1519199802 4 | licenseType: Pro 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Editor/SvgImporterWindow.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 895e76970e8e8974595848d7fbe44dfe 3 | timeCreated: 1519447087 4 | licenseType: Pro 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Editor/Artees.SVGImporter.Editor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Artees.SVGImporter.Editor", 3 | "references": [], 4 | "optionalUnityReferences": [], 5 | "includePlatforms": [ 6 | "Editor" 7 | ], 8 | "excludePlatforms": [], 9 | "allowUnsafeCode": false, 10 | "overrideReferences": false, 11 | "precompiledReferences": [], 12 | "autoReferenced": true, 13 | "defineConstraints": [], 14 | "versionDefines": [] 15 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "name" : "games.artees.svg-importer", 4 | "version" : "2.0.1", 5 | "displayName" : "SVG Importer", 6 | "description" : "SVG Importer for Unity", 7 | "unity" : "2021.3", 8 | "unityRelease" : "", 9 | "dependencies" : { 10 | }, 11 | "keywords" : [ 12 | ], 13 | "author" : { 14 | "name" : "Artees", 15 | "email" : "yo@artees.games", 16 | "url" : "https://github.com/Artees/SVGImporter" 17 | } 18 | } -------------------------------------------------------------------------------- /package.jsonpackage: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "name" : "games.artees.svg-importer", 4 | "version" : "2.0.1", 5 | "displayName" : "SVG Importer", 6 | "description" : "SVG Importer for Unity", 7 | "unity" : "2021.3", 8 | "unityRelease" : "", 9 | "dependencies" : { 10 | }, 11 | "keywords" : [ 12 | ], 13 | "author" : { 14 | "name" : "Artees", 15 | "email" : "yo@artees.games", 16 | "url" : "https://github.com/Artees/SVGImporter" 17 | } 18 | } -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 54171ecf039668f8e8e2ae6fdd49e1d8 3 | ScriptedImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 2 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | script: {fileID: 11500000, guid: 305d72b64a2242c0b6ff1d70a6bc89f4, type: 3} 11 | name: games.artees.svg-importer 12 | version: 2.0.0 13 | displayName: SVG Importer 14 | description: SVG Importer for Unity 15 | unity: 2019.2 16 | unityRelease: 17 | dependencies: 18 | keyValuePairs: [] 19 | keywords: [] 20 | author: 21 | name: Artees 22 | email: yo@artees.games 23 | url: https://github.com/Artees/SVGImporter 24 | autoExportJson: 1 25 | registryUrl: https://upm.artees.games:4873 26 | -------------------------------------------------------------------------------- /package.jsonpackage.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b8d4782118b976d449697c718f369f46 3 | ScriptedImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 2 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | script: {fileID: 11500000, guid: 305d72b64a2242c0b6ff1d70a6bc89f4, type: 3} 11 | name: games.artees.svg-importer 12 | version: 2.0.1 13 | displayName: SVG Importer 14 | description: SVG Importer for Unity 15 | unity: 2021.3 16 | unityRelease: 17 | dependencies: 18 | keyValuePairs: [] 19 | keywords: [] 20 | author: 21 | name: Artees 22 | email: yo@artees.games 23 | url: https://github.com/Artees/SVGImporter 24 | autoExportJson: 1 25 | registryUrl: https://upm.artees.games:4873 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SVG Importer for Unity 2 | 3 | [![openupm](https://img.shields.io/npm/v/games.artees.svg-importer?label=openupm®istry_uri=https://package.openupm.com)](https://openupm.com/packages/games.artees.svg-importer/) 4 | 5 | This script allows you to use SVG files as sprites for your Unity project. It should work on any Unity platforms. 6 | 7 | 8 | # Installation 9 | 10 | 1. Download and install Inkscape from its [official website](https://inkscape.org/). 11 | 2. Install the package **games.artees.svg-importer** using [my package registry](https://artees.games/upm). Or install via the [OpenUPM registry](https://openupm.com/packages/games.artees.svg-importer/). 12 | 3. If you run into an error, select *Window > Artees > SVG Importer* and enter the path to the directory where Inkscape is installed. 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /[Ll]ibrary/ 2 | /[Tt]emp/ 3 | /[Oo]bj/ 4 | /[Bb]uild/ 5 | /[Bb]uilds/ 6 | /Assets/AssetStoreTools* 7 | 8 | # Visual Studio 2015 cache directory 9 | /.vs/ 10 | 11 | # Autogenerated VS/MD/Consulo solution and project files 12 | ExportedObj/ 13 | .consulo/ 14 | *.csproj 15 | *.unityproj 16 | *.sln 17 | *.suo 18 | *.tmp 19 | *.user 20 | *.userprefs 21 | *.pidb 22 | *.booproj 23 | *.svd 24 | *.pdb 25 | *.png 26 | 27 | # Unity3D generated meta files 28 | *.pidb.meta 29 | 30 | # Unity3D Generated File On Crash Reports 31 | sysinfo.txt 32 | 33 | # Builds 34 | *.apk 35 | *.unitypackage 36 | /.collabignore 37 | /.idea/.idea.SvgToPngConverter 38 | /Assets/Plugins/Editor/JetBrains 39 | /Assets/Plugins/Editor/JetBrains.meta 40 | /Assets/Plugins/Editor.meta 41 | /Assets/Plugins.meta 42 | /Assets/Resources/SvgImporterSettings.asset 43 | /Assets/Resources/SvgImporterSettings.asset.meta 44 | /Assets/Resources.meta 45 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Artees 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Editor/SvgImporterSettings.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics.CodeAnalysis; 2 | using System.IO; 3 | using UnityEditor; 4 | using UnityEngine; 5 | using UnityEngine.Serialization; 6 | 7 | namespace Artees.SVGImporter.Editor 8 | { 9 | internal class SvgImporterSettings : ScriptableObject 10 | { 11 | public static SvgImporterSettings Load() 12 | { 13 | const string path = "Assets/Resources/SvgImporterSettings.asset"; 14 | var settings = AssetDatabase.LoadAssetAtPath(path); 15 | if (settings != null) return settings; 16 | settings = CreateInstance(); 17 | Directory.CreateDirectory("Assets/Resources"); 18 | AssetDatabase.CreateAsset(settings, path); 19 | return settings; 20 | } 21 | 22 | [FormerlySerializedAs("InkscapeExecutable"), SerializeField] 23 | private string inkscapeExecutable = 24 | #if UNITY_EDITOR_OSX 25 | "/Applications/Inkscape.app/Contents/Resources/bin/inkscape"; 26 | #else 27 | "inkscape"; 28 | #endif 29 | 30 | [FormerlySerializedAs("DefaultPixelDataStorage"), SerializeField] 31 | private SvgPixelDataStorage defaultPixelDataStorage = SvgPixelDataStorage.Metadata; 32 | 33 | [SuppressMessage("ReSharper", "ConvertToAutoProperty", Justification = "Serialized")] 34 | public string InkscapeExecutable 35 | { 36 | get => inkscapeExecutable; 37 | set => inkscapeExecutable = value; 38 | } 39 | 40 | [SuppressMessage("ReSharper", "ConvertToAutoProperty", Justification = "Serialized")] 41 | public SvgPixelDataStorage DefaultPixelDataStorage 42 | { 43 | get => defaultPixelDataStorage; 44 | set => defaultPixelDataStorage = value; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /Editor/SvgImporterWindow.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | using UnityEngine; 3 | 4 | namespace Artees.SVGImporter.Editor 5 | { 6 | internal class SvgImporterWindow : EditorWindow 7 | { 8 | [MenuItem("Window/Artees/SVG Importer")] 9 | public static void ShowWindow() 10 | { 11 | var window = GetWindow(true, "SVG Importer"); 12 | window.Show(); 13 | } 14 | 15 | private SvgImporterSettings _settings; 16 | 17 | private void Awake() 18 | { 19 | _settings = SvgImporterSettings.Load(); 20 | minSize = new Vector2(300f, 150f); 21 | position = new Rect(position.position, minSize); 22 | } 23 | 24 | private void OnGUI() 25 | { 26 | GUILayout.FlexibleSpace(); 27 | if (GUILayout.Button("Download Inkscape")) 28 | { 29 | Application.OpenURL("https://inkscape.org/"); 30 | } 31 | 32 | GUILayout.FlexibleSpace(); 33 | GUILayout.Label("Inkscape executable:", EditorStyles.boldLabel); 34 | GUILayout.BeginHorizontal(); 35 | var minWidth = GUILayout.MinWidth(10f); 36 | _settings.InkscapeExecutable = 37 | GUILayout.TextField(_settings.InkscapeExecutable, minWidth); 38 | var maxWidth = GUILayout.MaxWidth(100f); 39 | if (GUILayout.Button("Browse", maxWidth)) 40 | { 41 | _settings.InkscapeExecutable = EditorUtility.OpenFilePanel("Inkscape executable", 42 | _settings.InkscapeExecutable, ""); 43 | } 44 | 45 | GUILayout.EndHorizontal(); 46 | GUILayout.FlexibleSpace(); 47 | var metadata = CreateToggleGroup("Default pixel data storage:", 48 | _settings.DefaultPixelDataStorage == SvgPixelDataStorage.Metadata, 49 | "Metadata", 50 | "Png"); 51 | _settings.DefaultPixelDataStorage = 52 | metadata ? SvgPixelDataStorage.Metadata : SvgPixelDataStorage.Png; 53 | GUILayout.FlexibleSpace(); 54 | } 55 | 56 | private static bool CreateToggleGroup(string header, bool value, string labelTrue, string labelFalse) 57 | { 58 | GUILayout.Label(header, EditorStyles.boldLabel); 59 | var result = EditorGUILayout.Toggle(labelTrue, value, EditorStyles.radioButton); 60 | result = !EditorGUILayout.Toggle(labelFalse, !result, EditorStyles.radioButton); 61 | return result; 62 | } 63 | 64 | private void OnDestroy() 65 | { 66 | EditorUtility.SetDirty(_settings); 67 | AssetDatabase.SaveAssets(); 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /Editor/SvgImporter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.IO; 4 | using System.Linq; 5 | using UnityEditor; 6 | using UnityEditor.AssetImporters; 7 | using UnityEngine; 8 | using UnityEngine.Serialization; 9 | using Debug = UnityEngine.Debug; 10 | 11 | namespace Artees.SVGImporter.Editor 12 | { 13 | [Serializable, ScriptedImporter(3, "svg")] 14 | internal class SvgImporter : ScriptedImporter 15 | { 16 | #pragma warning disable 0649 17 | [FormerlySerializedAs("PixelDataStorage"), SerializeField] 18 | private SvgPixelDataStorage pixelDataStorage; 19 | #pragma warning restore 0649 20 | 21 | [FormerlySerializedAs("_data"), SerializeField, HideInInspector] 22 | private string data; 23 | 24 | public override void OnImportAsset(AssetImportContext ctx) 25 | { 26 | var relativeSvgPath = ctx.assetPath; 27 | if (string.IsNullOrEmpty(relativeSvgPath) || relativeSvgPath.StartsWith("Packages/")) return; 28 | var settings = SvgImporterSettings.Load(); 29 | var texture = new Texture2D(4, 4) {alphaIsTransparency = true}; 30 | var svgFolder = Path.GetDirectoryName(relativeSvgPath)?.Replace("\\", "/"); 31 | const string pngFolderName = "Rasterized"; 32 | var pngFolder = $"{svgFolder}/{pngFolderName}"; 33 | if (!AssetDatabase.IsValidFolder(pngFolder)) 34 | { 35 | AssetDatabase.CreateFolder(svgFolder, pngFolderName); 36 | EditorUtility.SetDirty(this); 37 | AssetDatabase.ImportAsset(relativeSvgPath); 38 | } 39 | 40 | var relativePngPath = $"{pngFolder}/{Path.GetFileNameWithoutExtension(relativeSvgPath)}.png"; 41 | const string assetsDirectory = "Assets"; 42 | var dataPath = Application.dataPath; 43 | var svgPath = dataPath.Replace(assetsDirectory, relativeSvgPath); 44 | var pngPath = dataPath.Replace(assetsDirectory, relativePngPath); 45 | var obsoletePngPath = Path.ChangeExtension(relativeSvgPath, "png"); 46 | if (File.Exists(obsoletePngPath)) 47 | { 48 | AssetDatabase.MoveAsset(obsoletePngPath, relativePngPath); 49 | } 50 | ExportPng(settings.InkscapeExecutable, svgPath, pngPath); 51 | if (File.Exists(pngPath)) 52 | { 53 | var bytes = ReadPng(pngFolder, relativePngPath, pngPath, settings); 54 | texture.LoadImage(bytes); 55 | } 56 | else 57 | { 58 | var bytes = Convert.FromBase64String(data); 59 | texture.LoadImage(bytes); 60 | var message = $"File \"{pngPath}\" was not created."; 61 | Debug.LogError(message); 62 | } 63 | 64 | var svgName = Path.ChangeExtension(relativeSvgPath.Split('/').Last(), string.Empty) 65 | .Replace(".", string.Empty); 66 | texture.name = svgName + " Texture"; 67 | var rect = new Rect(0f, 0f, texture.width, texture.height); 68 | var pivot = new Vector2(0.5f, 0.5f); 69 | var sprite = Sprite.Create(texture, rect, pivot); 70 | sprite.name = svgName + " Sprite"; 71 | ctx.AddObjectToAsset("texture", texture, texture); 72 | ctx.AddObjectToAsset("sprite", sprite); 73 | ctx.SetMainObject(sprite); 74 | } 75 | 76 | private byte[] ReadPng(string pngFolder, string relativePngPath, string pngPath, SvgImporterSettings settings) 77 | { 78 | var bytes = File.ReadAllBytes(pngPath); 79 | if (pixelDataStorage == SvgPixelDataStorage.Png || 80 | pixelDataStorage == SvgPixelDataStorage.Default && 81 | settings.DefaultPixelDataStorage == SvgPixelDataStorage.Png) 82 | { 83 | AssetDatabase.ImportAsset(relativePngPath); 84 | } 85 | else 86 | { 87 | AssetDatabase.DeleteAsset(relativePngPath); 88 | var isPngFolderEmpty = !AssetDatabase.GetAllAssetPaths() 89 | .Any(s => s.StartsWith(pngFolder) && s != pngFolder); 90 | if (isPngFolderEmpty) 91 | { 92 | AssetDatabase.DeleteAsset(pngFolder); 93 | } 94 | } 95 | 96 | data = Convert.ToBase64String(bytes, Base64FormattingOptions.InsertLineBreaks); 97 | return bytes; 98 | } 99 | 100 | private static void ExportPng(string inkscape, string svgPath, string pngPath) 101 | { 102 | var startInfo = new ProcessStartInfo 103 | { 104 | FileName = inkscape, 105 | Arguments = $"\"{svgPath}\" -o \"{pngPath}\"", 106 | UseShellExecute = false, 107 | RedirectStandardError = true, 108 | }; 109 | using (var process = new Process()) 110 | { 111 | process.StartInfo = startInfo; 112 | try 113 | { 114 | process.Start(); 115 | process.WaitForExit(); 116 | var error = process.StandardError.ReadToEnd(); 117 | if (!string.IsNullOrEmpty(error)) Debug.LogError(error); 118 | } 119 | catch (Exception) 120 | { 121 | const string mes = "Inkscape not found."; 122 | Debug.LogError(mes); 123 | SvgImporterWindow.ShowWindow(); 124 | } 125 | } 126 | } 127 | } 128 | } 129 | --------------------------------------------------------------------------------