├── .idea ├── .idea.GSImporter │ └── .idea │ │ ├── .gitignore │ │ ├── encodings.xml │ │ ├── indexLayout.xml │ │ └── vcs.xml └── .idea.UnityGoogleSheetsImporter.dir │ └── .idea │ ├── .gitignore │ ├── encodings.xml │ ├── indexLayout.xml │ └── vcs.xml ├── AB_GoogleSheetImporter.asmdef ├── AB_GoogleSheetImporter.asmdef.meta ├── Editor.meta ├── Editor ├── AB_GoogleSheetImporterEditor.asmdef ├── AB_GoogleSheetImporterEditor.asmdef.meta ├── GSimporterEditor.cs ├── GSimporterEditor.cs.meta ├── TableData.cs └── TableData.cs.meta ├── Images.meta ├── Images ├── photo_1.jpg ├── photo_1.jpg.meta ├── photo_2.png ├── photo_2.png.meta ├── photo_3.png └── photo_3.png.meta ├── README.md ├── README.md.meta ├── README_en.md ├── README_en.md.meta ├── Runtime.meta ├── Runtime ├── FileFormat.cs ├── FileFormat.cs.meta ├── GSImporter.cs └── GSImporter.cs.meta ├── package.json └── package.json.meta /.idea/.idea.GSImporter/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Rider ignored files 5 | /.idea.GSImporter.iml 6 | /contentModel.xml 7 | /modules.xml 8 | /projectSettingsUpdater.xml 9 | # Editor-based HTTP Client requests 10 | /httpRequests/ 11 | # Datasource local storage ignored files 12 | /dataSources/ 13 | /dataSources.local.xml 14 | -------------------------------------------------------------------------------- /.idea/.idea.GSImporter/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/.idea.GSImporter/.idea/indexLayout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/.idea.GSImporter/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/.idea.UnityGoogleSheetsImporter.dir/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Rider ignored files 5 | /modules.xml 6 | /projectSettingsUpdater.xml 7 | /contentModel.xml 8 | /.idea.UnityGoogleSheetsImporter.iml 9 | # Editor-based HTTP Client requests 10 | /httpRequests/ 11 | # Datasource local storage ignored files 12 | /dataSources/ 13 | /dataSources.local.xml 14 | -------------------------------------------------------------------------------- /.idea/.idea.UnityGoogleSheetsImporter.dir/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/.idea.UnityGoogleSheetsImporter.dir/.idea/indexLayout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/.idea.UnityGoogleSheetsImporter.dir/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /AB_GoogleSheetImporter.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "AB_GoogleSheetImporter", 3 | "rootNamespace": "", 4 | "references": [], 5 | "includePlatforms": [], 6 | "excludePlatforms": [], 7 | "allowUnsafeCode": false, 8 | "overrideReferences": false, 9 | "precompiledReferences": [], 10 | "autoReferenced": true, 11 | "defineConstraints": [], 12 | "versionDefines": [], 13 | "noEngineReferences": false 14 | } -------------------------------------------------------------------------------- /AB_GoogleSheetImporter.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4d631c33236c5a24db12fce684b2bbca 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 20e0d53f49807634ab12336c7164c0e6 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/AB_GoogleSheetImporterEditor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "AB_GoogleSheetImporterEditor", 3 | "rootNamespace": "", 4 | "references": [ 5 | "AB_GoogleSheetImporter" 6 | ], 7 | "includePlatforms": [ 8 | "Editor" 9 | ], 10 | "excludePlatforms": [], 11 | "allowUnsafeCode": false, 12 | "overrideReferences": false, 13 | "precompiledReferences": [], 14 | "autoReferenced": true, 15 | "defineConstraints": [], 16 | "versionDefines": [], 17 | "noEngineReferences": false 18 | } -------------------------------------------------------------------------------- /Editor/AB_GoogleSheetImporterEditor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a91bac0f03d9ec54f8cf951f4ffa6753 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Editor/GSimporterEditor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Runtime.Serialization.Formatters.Binary; 5 | using System.Threading.Tasks; 6 | 7 | using UnityEditor; 8 | 9 | using UnityEngine; 10 | using UnityEngine.UIElements; 11 | 12 | namespace AB_GoogleSheetImporter.Editor 13 | { 14 | public class GSImporterEditor : EditorWindow 15 | { 16 | private string _savePath; 17 | private List _content; 18 | private BinaryFormatter _formatter = new(); 19 | 20 | [MenuItem("Tools/GoogleSheetsImporter")] 21 | public static void ShowExample() 22 | { 23 | var wnd = GetWindow(); 24 | wnd.titleContent = new GUIContent("GoogleSheetsImporter"); 25 | } 26 | 27 | private void OnDisable() 28 | { 29 | SaveData(); 30 | } 31 | 32 | public void CreateGUI() 33 | { 34 | var folderPath = Application.dataPath + "/Editor"; 35 | if (!Directory.Exists(folderPath)) 36 | { 37 | Directory.CreateDirectory(folderPath); 38 | } 39 | 40 | _savePath = folderPath + "/GSImporterData.dat"; 41 | _content = GetContent(); 42 | 43 | var root = rootVisualElement; 44 | 45 | var scrollContainer = new VisualElement(); 46 | scrollContainer.style.flexGrow = 1; 47 | 48 | var scroll = new ScrollView(ScrollViewMode.Vertical); 49 | scroll.style.flexGrow = 1; 50 | scroll.style.height = 400; 51 | 52 | scrollContainer.Add(scroll); 53 | 54 | foreach (var tableData in _content) 55 | { 56 | CreateDataBox(scroll, tableData); 57 | } 58 | 59 | root.Add(scrollContainer); 60 | 61 | //Create buttons 62 | var buttonsContainer = new VisualElement(); 63 | buttonsContainer.style.flexGrow = 0; 64 | buttonsContainer.style.justifyContent = new StyleEnum(Justify.FlexEnd); 65 | 66 | var addButton = CreateButton("Add", buttonsContainer); 67 | addButton.RegisterCallback(x => 68 | { 69 | SaveData(); 70 | CreateDataBox(scroll); 71 | }); 72 | 73 | var downloadButton = CreateButton("Download", buttonsContainer); 74 | downloadButton.RegisterCallback(x => DownloadAsync()); 75 | 76 | root.Add(buttonsContainer); 77 | } 78 | 79 | private Button CreateButton(string text, VisualElement container) 80 | { 81 | var button = new Button() {text = text}; 82 | button.style.height = 35; 83 | button.style.marginTop = 2; 84 | button.style.marginBottom = 2; 85 | container.Add(button); 86 | return button; 87 | } 88 | 89 | private void CreateDataBox(VisualElement root, TableData tableData = null) 90 | { 91 | //Create view 92 | var box = new Box(); 93 | box.style.marginBottom = 20; 94 | var selectedToggleField = new Toggle("Selected"); 95 | var downloadUrlField = new TextField("Download url path:"); 96 | var localPathField = new TextField("Local path:"); 97 | var nameField = new TextField("Name:"); 98 | var enumField = new EnumField("File format:", FileFormat.csv); 99 | 100 | if (tableData != null) 101 | { 102 | selectedToggleField.value = tableData.Selected; 103 | downloadUrlField.value = tableData.DownloadUrlPath; 104 | localPathField.value = tableData.LocalPath; 105 | nameField.value = tableData.Name; 106 | enumField.value = tableData.FileFormat; 107 | } 108 | else 109 | { 110 | selectedToggleField.value = true; 111 | } 112 | 113 | box.Add(selectedToggleField); 114 | box.Add(downloadUrlField); 115 | box.Add(localPathField); 116 | box.Add(nameField); 117 | box.Add(enumField); 118 | root.Add(box); 119 | 120 | //Bind data 121 | tableData ??= new TableData(); 122 | tableData.Selected = true; 123 | selectedToggleField.RegisterCallback>(x => tableData.Selected = x.newValue); 124 | downloadUrlField.RegisterCallback(x => tableData.DownloadUrlPath = x.newData); 125 | localPathField.RegisterCallback(x => tableData.LocalPath = x.newData); 126 | nameField.RegisterCallback(x => tableData.Name = x.newData); 127 | enumField.RegisterValueChangedCallback(x => tableData.FileFormat = (FileFormat) x.newValue); 128 | 129 | if (_content.Contains(tableData) == false) 130 | { 131 | _content.Add(tableData); 132 | } 133 | 134 | var removeButton = new Button(() => 135 | { 136 | root.Remove(box); 137 | _content.Remove(tableData); 138 | SaveData(); 139 | }); 140 | removeButton.text = "Remove"; 141 | box.Add(removeButton); 142 | } 143 | 144 | private List GetContent() 145 | { 146 | if (File.Exists(_savePath)) 147 | { 148 | using var fs = new FileStream(_savePath, FileMode.OpenOrCreate); 149 | return _formatter.Deserialize(fs) as List; 150 | } 151 | 152 | return new List(); 153 | } 154 | 155 | private void SaveData() 156 | { 157 | using var fs = new FileStream(_savePath, FileMode.OpenOrCreate); 158 | _formatter.Serialize(fs, _content); 159 | } 160 | 161 | private async void DownloadAsync() 162 | { 163 | EditorUtility.DisplayProgressBar("GoogleSheetsImporter", "Downloading...", 0); 164 | try 165 | { 166 | for (int i = 0; i < _content.Count; i++) 167 | { 168 | var data = _content[i]; 169 | if (data.Selected == false) continue; 170 | 171 | await GSImporter.DownloadAsync( 172 | data.Name, 173 | data.DownloadUrlPath, 174 | data.LocalPath, 175 | data.FileFormat); 176 | 177 | await Task.Delay(TimeSpan.FromSeconds(0.2f)); 178 | 179 | EditorUtility.DisplayProgressBar("GoogleSheetsImporter", "Downloading...", 180 | (float) 1 / _content.Count - i); 181 | } 182 | } 183 | catch (Exception e) 184 | { 185 | EditorUtility.ClearProgressBar(); 186 | Debug.LogException(e); 187 | throw; 188 | } 189 | 190 | AssetDatabase.Refresh(); 191 | EditorUtility.ClearProgressBar(); 192 | } 193 | } 194 | } -------------------------------------------------------------------------------- /Editor/GSimporterEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c122af85bfe3a234e8e610c7fc20e767 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/TableData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace AB_GoogleSheetImporter.Editor 4 | { 5 | [Serializable] 6 | public class TableData 7 | { 8 | public bool Selected; 9 | public string DownloadUrlPath; 10 | public string LocalPath; 11 | public string Name; 12 | public FileFormat FileFormat; 13 | } 14 | } -------------------------------------------------------------------------------- /Editor/TableData.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8ad8934c3bac4596b2449cc82fecf59f 3 | timeCreated: 1659280064 -------------------------------------------------------------------------------- /Images.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c797c0fb31d2d104bad9ec52ab6f62f9 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Images/photo_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AndreyBirchenko/UnityGoogleSheetsImporter/e1efb3e1843ea8209dd73c3b5838e9b49c06f119/Images/photo_1.jpg -------------------------------------------------------------------------------- /Images/photo_1.jpg.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 92c16f3bac8cd8549bd7c1f3b996489e 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | flipGreenChannel: 0 24 | isReadable: 0 25 | streamingMipmaps: 0 26 | streamingMipmapsPriority: 0 27 | vTOnly: 0 28 | ignoreMipmapLimit: 0 29 | grayScaleToAlpha: 0 30 | generateCubemap: 6 31 | cubemapConvolution: 0 32 | seamlessCubemap: 0 33 | textureFormat: 1 34 | maxTextureSize: 2048 35 | textureSettings: 36 | serializedVersion: 2 37 | filterMode: 1 38 | aniso: 1 39 | mipBias: 0 40 | wrapU: 1 41 | wrapV: 1 42 | wrapW: 1 43 | nPOTScale: 0 44 | lightmap: 0 45 | compressionQuality: 50 46 | spriteMode: 1 47 | spriteExtrude: 1 48 | spriteMeshType: 1 49 | alignment: 0 50 | spritePivot: {x: 0.5, y: 0.5} 51 | spritePixelsToUnits: 100 52 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 53 | spriteGenerateFallbackPhysicsShape: 1 54 | alphaUsage: 1 55 | alphaIsTransparency: 1 56 | spriteTessellationDetail: -1 57 | textureType: 8 58 | textureShape: 1 59 | singleChannelComponent: 0 60 | flipbookRows: 1 61 | flipbookColumns: 1 62 | maxTextureSizeSet: 0 63 | compressionQualitySet: 0 64 | textureFormatSet: 0 65 | ignorePngGamma: 0 66 | applyGammaDecoding: 0 67 | swizzle: 50462976 68 | cookieLightType: 0 69 | platformSettings: 70 | - serializedVersion: 3 71 | buildTarget: DefaultTexturePlatform 72 | maxTextureSize: 2048 73 | resizeAlgorithm: 0 74 | textureFormat: -1 75 | textureCompression: 1 76 | compressionQuality: 50 77 | crunchedCompression: 0 78 | allowsAlphaSplitting: 0 79 | overridden: 0 80 | ignorePlatformSupport: 0 81 | androidETC2FallbackOverride: 0 82 | forceMaximumCompressionQuality_BC6H_BC7: 0 83 | - serializedVersion: 3 84 | buildTarget: Standalone 85 | maxTextureSize: 2048 86 | resizeAlgorithm: 0 87 | textureFormat: -1 88 | textureCompression: 1 89 | compressionQuality: 50 90 | crunchedCompression: 0 91 | allowsAlphaSplitting: 0 92 | overridden: 0 93 | ignorePlatformSupport: 0 94 | androidETC2FallbackOverride: 0 95 | forceMaximumCompressionQuality_BC6H_BC7: 0 96 | - serializedVersion: 3 97 | buildTarget: Server 98 | maxTextureSize: 2048 99 | resizeAlgorithm: 0 100 | textureFormat: -1 101 | textureCompression: 1 102 | compressionQuality: 50 103 | crunchedCompression: 0 104 | allowsAlphaSplitting: 0 105 | overridden: 0 106 | ignorePlatformSupport: 0 107 | androidETC2FallbackOverride: 0 108 | forceMaximumCompressionQuality_BC6H_BC7: 0 109 | spriteSheet: 110 | serializedVersion: 2 111 | sprites: [] 112 | outline: [] 113 | physicsShape: [] 114 | bones: [] 115 | spriteID: 5e97eb03825dee720800000000000000 116 | internalID: 0 117 | vertices: [] 118 | indices: 119 | edges: [] 120 | weights: [] 121 | secondaryTextures: [] 122 | nameFileIdTable: {} 123 | mipmapLimitGroupName: 124 | pSDRemoveMatte: 0 125 | userData: 126 | assetBundleName: 127 | assetBundleVariant: 128 | -------------------------------------------------------------------------------- /Images/photo_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AndreyBirchenko/UnityGoogleSheetsImporter/e1efb3e1843ea8209dd73c3b5838e9b49c06f119/Images/photo_2.png -------------------------------------------------------------------------------- /Images/photo_2.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 474c3a54032aed848a1ede5d20e468ca 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | flipGreenChannel: 0 24 | isReadable: 0 25 | streamingMipmaps: 0 26 | streamingMipmapsPriority: 0 27 | vTOnly: 0 28 | ignoreMipmapLimit: 0 29 | grayScaleToAlpha: 0 30 | generateCubemap: 6 31 | cubemapConvolution: 0 32 | seamlessCubemap: 0 33 | textureFormat: 1 34 | maxTextureSize: 2048 35 | textureSettings: 36 | serializedVersion: 2 37 | filterMode: 1 38 | aniso: 1 39 | mipBias: 0 40 | wrapU: 1 41 | wrapV: 1 42 | wrapW: 1 43 | nPOTScale: 0 44 | lightmap: 0 45 | compressionQuality: 50 46 | spriteMode: 1 47 | spriteExtrude: 1 48 | spriteMeshType: 1 49 | alignment: 0 50 | spritePivot: {x: 0.5, y: 0.5} 51 | spritePixelsToUnits: 100 52 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 53 | spriteGenerateFallbackPhysicsShape: 1 54 | alphaUsage: 1 55 | alphaIsTransparency: 1 56 | spriteTessellationDetail: -1 57 | textureType: 8 58 | textureShape: 1 59 | singleChannelComponent: 0 60 | flipbookRows: 1 61 | flipbookColumns: 1 62 | maxTextureSizeSet: 0 63 | compressionQualitySet: 0 64 | textureFormatSet: 0 65 | ignorePngGamma: 0 66 | applyGammaDecoding: 0 67 | swizzle: 50462976 68 | cookieLightType: 0 69 | platformSettings: 70 | - serializedVersion: 3 71 | buildTarget: DefaultTexturePlatform 72 | maxTextureSize: 2048 73 | resizeAlgorithm: 0 74 | textureFormat: -1 75 | textureCompression: 1 76 | compressionQuality: 50 77 | crunchedCompression: 0 78 | allowsAlphaSplitting: 0 79 | overridden: 0 80 | ignorePlatformSupport: 0 81 | androidETC2FallbackOverride: 0 82 | forceMaximumCompressionQuality_BC6H_BC7: 0 83 | - serializedVersion: 3 84 | buildTarget: Standalone 85 | maxTextureSize: 2048 86 | resizeAlgorithm: 0 87 | textureFormat: -1 88 | textureCompression: 1 89 | compressionQuality: 50 90 | crunchedCompression: 0 91 | allowsAlphaSplitting: 0 92 | overridden: 0 93 | ignorePlatformSupport: 0 94 | androidETC2FallbackOverride: 0 95 | forceMaximumCompressionQuality_BC6H_BC7: 0 96 | - serializedVersion: 3 97 | buildTarget: Server 98 | maxTextureSize: 2048 99 | resizeAlgorithm: 0 100 | textureFormat: -1 101 | textureCompression: 1 102 | compressionQuality: 50 103 | crunchedCompression: 0 104 | allowsAlphaSplitting: 0 105 | overridden: 0 106 | ignorePlatformSupport: 0 107 | androidETC2FallbackOverride: 0 108 | forceMaximumCompressionQuality_BC6H_BC7: 0 109 | spriteSheet: 110 | serializedVersion: 2 111 | sprites: [] 112 | outline: [] 113 | physicsShape: [] 114 | bones: [] 115 | spriteID: 5e97eb03825dee720800000000000000 116 | internalID: 0 117 | vertices: [] 118 | indices: 119 | edges: [] 120 | weights: [] 121 | secondaryTextures: [] 122 | nameFileIdTable: {} 123 | mipmapLimitGroupName: 124 | pSDRemoveMatte: 0 125 | userData: 126 | assetBundleName: 127 | assetBundleVariant: 128 | -------------------------------------------------------------------------------- /Images/photo_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AndreyBirchenko/UnityGoogleSheetsImporter/e1efb3e1843ea8209dd73c3b5838e9b49c06f119/Images/photo_3.png -------------------------------------------------------------------------------- /Images/photo_3.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 31d8fe277d44b2047b64a88638c218f8 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | flipGreenChannel: 0 24 | isReadable: 0 25 | streamingMipmaps: 0 26 | streamingMipmapsPriority: 0 27 | vTOnly: 0 28 | ignoreMipmapLimit: 0 29 | grayScaleToAlpha: 0 30 | generateCubemap: 6 31 | cubemapConvolution: 0 32 | seamlessCubemap: 0 33 | textureFormat: 1 34 | maxTextureSize: 2048 35 | textureSettings: 36 | serializedVersion: 2 37 | filterMode: 1 38 | aniso: 1 39 | mipBias: 0 40 | wrapU: 1 41 | wrapV: 1 42 | wrapW: 1 43 | nPOTScale: 0 44 | lightmap: 0 45 | compressionQuality: 50 46 | spriteMode: 1 47 | spriteExtrude: 1 48 | spriteMeshType: 1 49 | alignment: 0 50 | spritePivot: {x: 0.5, y: 0.5} 51 | spritePixelsToUnits: 100 52 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 53 | spriteGenerateFallbackPhysicsShape: 1 54 | alphaUsage: 1 55 | alphaIsTransparency: 1 56 | spriteTessellationDetail: -1 57 | textureType: 8 58 | textureShape: 1 59 | singleChannelComponent: 0 60 | flipbookRows: 1 61 | flipbookColumns: 1 62 | maxTextureSizeSet: 0 63 | compressionQualitySet: 0 64 | textureFormatSet: 0 65 | ignorePngGamma: 0 66 | applyGammaDecoding: 0 67 | swizzle: 50462976 68 | cookieLightType: 0 69 | platformSettings: 70 | - serializedVersion: 3 71 | buildTarget: DefaultTexturePlatform 72 | maxTextureSize: 2048 73 | resizeAlgorithm: 0 74 | textureFormat: -1 75 | textureCompression: 1 76 | compressionQuality: 50 77 | crunchedCompression: 0 78 | allowsAlphaSplitting: 0 79 | overridden: 0 80 | ignorePlatformSupport: 0 81 | androidETC2FallbackOverride: 0 82 | forceMaximumCompressionQuality_BC6H_BC7: 0 83 | - serializedVersion: 3 84 | buildTarget: Standalone 85 | maxTextureSize: 2048 86 | resizeAlgorithm: 0 87 | textureFormat: -1 88 | textureCompression: 1 89 | compressionQuality: 50 90 | crunchedCompression: 0 91 | allowsAlphaSplitting: 0 92 | overridden: 0 93 | ignorePlatformSupport: 0 94 | androidETC2FallbackOverride: 0 95 | forceMaximumCompressionQuality_BC6H_BC7: 0 96 | - serializedVersion: 3 97 | buildTarget: Server 98 | maxTextureSize: 2048 99 | resizeAlgorithm: 0 100 | textureFormat: -1 101 | textureCompression: 1 102 | compressionQuality: 50 103 | crunchedCompression: 0 104 | allowsAlphaSplitting: 0 105 | overridden: 0 106 | ignorePlatformSupport: 0 107 | androidETC2FallbackOverride: 0 108 | forceMaximumCompressionQuality_BC6H_BC7: 0 109 | spriteSheet: 110 | serializedVersion: 2 111 | sprites: [] 112 | outline: [] 113 | physicsShape: [] 114 | bones: [] 115 | spriteID: 5e97eb03825dee720800000000000000 116 | internalID: 0 117 | vertices: [] 118 | indices: 119 | edges: [] 120 | weights: [] 121 | secondaryTextures: [] 122 | nameFileIdTable: {} 123 | mipmapLimitGroupName: 124 | pSDRemoveMatte: 0 125 | userData: 126 | assetBundleName: 127 | assetBundleVariant: 128 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UnityGoogleSheetsImporter - простой инструмент для импортирования гугл таблиц в ваш Unity проект. 2 | *Read this in other languages: [Русский](https://github.com/AndreyBirchenko/UnityGoogleSheetsImporter/blob/master/README.md), [English](https://github.com/AndreyBirchenko/UnityGoogleSheetsImporter/blob/master/README_en.md)* 3 | 4 | ## Установка 5 | > **ВАЖНО!** Если вы используете версию Unity ниже чем 2021.3 работоспособность не гарантируется. 6 | 7 | ## В виде unity модуля 8 | Поддерживается установка в виде unity-модуля через git-ссылку в PackageManager или прямое редактирование `Packages/manifest.json`: 9 | ``` 10 | "com.anbi.google-sheet-importer": "https://github.com/AndreyBirchenko/UnityGoogleSheetsImporter.git", 11 | ``` 12 | 13 | ## Начало работы 14 | > **ВАЖНО!** Не рекомендуется использовать скачивание данных с GoogleDocs в релизных билдах: 15 | > * Время отклика может достигать десятка секунд. 16 | > * Лимит по обращению к документу может быстро переполниться и документ будет заблокирован на какое-то время. 17 | 18 | Вы можете скачивать таблицы как походу исполнения программы так и в эдиторе с помощью UI утилиты 19 | 20 | ### Скачивание с помощью утилиты 21 | > **ВАЖНО!** При скачивании с помощью утилиты всегда будет скачана только первая страница таблицы 22 | 23 | Откройте окно загрузки таблиц. Для этого нажмите **Tools -> GoogleSheetsImporter**. 24 | 25 | Images/photo_1.jpg 26 | 27 | Нажмите **Add** чтобы добавить новую таблицу. 28 | 29 | Images/photo_2.png 30 | 31 | В графу **Download url path:** вставьте [публичную](https://support.google.com/docs/answer/2494822?hl=en&co=GENIE.Platform%3DDesktop#zippy=) ссылку на гугл таблицу 32 | (это та ссылка которая появляется после того как вы нажали кнопку "Поделиться") 33 | 34 | В графу **Local path:** добавьте путь куда вы хотите сохранить таблицу 35 | > **ВАЖНО!** Путь уже содержит в себе папку Assets. То есть если вы хотите сохранить таблицу по пути Assets/MyFolder, то достаточно написать только MyFolder. Если директории не нуществует, то она будет создана автоматически. 36 | 37 | В графу **Name:** добавьте имя таблицы. 38 | 39 | В граве **File format:** выберете нужный формат. 40 | 41 | Нажмите **Download** и подождите пока таблица загрузится. 42 | 43 | ### Скачивание по ходу исполнения программы 44 | ```c# 45 | //Публичная ссылка на таблицу 46 | var url = "https://docs.google.com/spreadsheets/d/xxxx/edit?usp=sharing"; 47 | var csv = await GSImporter.DownloadCsvAsync(url); 48 | 49 | //Вы также можете скачать конкретную страницу по её id 50 | var sheetId = 0; 51 | var concretePageCsv = await GSImporter.DownloadCsvAsync(url, sheetId); 52 | ``` 53 | Чтобы получить id страницы вам нужно открыть гугл таблицу на нужной странице и скопировать цифры в ссылке после ```#gid=``` 54 | 55 | Images/photo_3.png 56 | 57 | ## Графа Selected 58 | Если у вас много таблиц и вы не хотите скачивать заново все, вы можете снять галочку Selected с тех, которые не нуждаются в обновлении. 59 | Те таблицы на которых стоит галочка Selected будут скачиваться заново каждый раз при нажатии кнопки Download. -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7a17763fa98ee4f449871b4f4554dbda 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /README_en.md: -------------------------------------------------------------------------------- 1 | # UnityGoogleSheetsImporter is a simple tool for importing Google tables into your Unity project. 2 | *Read this in other languages: [Русский](https://github.com/AndreyBirchenko/UnityGoogleSheetsImporter/blob/master/README.md), [English](https://github.com/AndreyBirchenko/UnityGoogleSheetsImporter/blob/master/README_en.md)* 3 | 4 | ## Installation 5 | > **IMPORTANT!** If you are using a Unity version lower than 2021.1, performance is not guaranteed. 6 | 7 | ## As a unity module 8 | Installation as a unity module via a git link in PackageManager or direct editing of `Packages/manifest.json`: 9 | ``` 10 | "com.anbi.google-sheet-importer": "https://github.com/AndreyBirchenko/UnityGoogleSheetsImporter.git", 11 | ``` 12 | 13 | ## Getting started 14 | > **IMPORTANT!** It is not recommended to use downloading data from Google Docs in release builds: 15 | > * Response time can reach ten seconds. 16 | > * The limit on accessing a document can quickly overflow and the document will be blocked for a while. 17 | 18 | You can download tables both after the program execution and in the editor using the UI utility 19 | 20 | ### Download using the utility 21 | > **IMPORTANT!** When downloading using the utility, only the first page of the table will always be downloaded 22 | 23 | Open the table loading window. To do this, click **Tools -> GoogleSheetsImporter**. 24 | 25 | Images/photo_1.jpg 26 | 27 | Click **Add** to add a new table. 28 | 29 | Images/photo_2.png 30 | 31 | In the column **Download url path:** insert [public](https://support.google.com/docs/answer/2494822?hl=en&co=GENIE.Platform%3DDesktop#zippy=) link to google table 32 | (this is the link that appears after you click the "Share" button) 33 | 34 | In the column **Local path:** add the path where you want to save the table 35 | > **IMPORTANT!** The path already contains the Assets folder. That is, if you want to save the table along the Assets/MyFolder path, then it is enough to write only MyFolder. If the directory does not exist, it will be created automatically. 36 | 37 | In the column **Name:** add a table name. 38 | 39 | In the column **File format:** select the desired format. 40 | 41 | Click **Download** and wait for the table to load. 42 | 43 | ### Downloading during the execution of the program 44 | ```c# 45 | //Public link to the table 46 | var url = "https://docs.google.com/spreadsheets/d/xxxx/edit?usp=sharing"; 47 | var csv = await GSImporter.DownloadCsvAsync(url); 48 | //You can also download a specific page by its id 49 | var sheetId = 0; 50 | var concretePageCsv = await GSImporter.DownloadCsvAsync(url, sheetId); 51 | ``` 52 | To get the page id, you need to open the Google spreadsheet on the desired page and copy the numbers in the link after ``#gid=`` 53 | Images/photo_3.png 54 | 55 | ## Selected toggle 56 | If you have a lot of tables and you don't want to download everything again, you can uncheck Selected from those that don't need updating. 57 | Those tables with the Selected check mark will be downloaded again every time you click the Download button. 58 | -------------------------------------------------------------------------------- /README_en.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1d8f7a2ec27eb8a4aba9949b05ca321d 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0a097c7446aec424eba1f5d3d7d4fac4 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/FileFormat.cs: -------------------------------------------------------------------------------- 1 | namespace AB_GoogleSheetImporter.Editor 2 | { 3 | public enum FileFormat 4 | { 5 | csv, 6 | tsv, 7 | ods 8 | } 9 | } -------------------------------------------------------------------------------- /Runtime/FileFormat.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1f5b87a4fbce4c9bb3b086ddda15e303 3 | timeCreated: 1659257853 -------------------------------------------------------------------------------- /Runtime/GSImporter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Runtime.CompilerServices; 4 | using System.Text.RegularExpressions; 5 | using System.Threading.Tasks; 6 | 7 | using UnityEngine; 8 | using UnityEngine.Networking; 9 | 10 | namespace AB_GoogleSheetImporter.Editor 11 | { 12 | public static class GSImporter 13 | { 14 | private static readonly Regex _regex; 15 | 16 | static GSImporter() 17 | { 18 | _regex = new Regex(@"https://docs\.google\.com/spreadsheets/d/(.+)/"); 19 | } 20 | 21 | public static async Task DownloadCsvAsync(string url) 22 | { 23 | return await DownloadCsvAsync(url, 0); 24 | } 25 | 26 | public static async Task DownloadCsvAsync(string url, int sheetId) 27 | { 28 | var stringFormat = GetStringFormat(FileFormat.csv); 29 | var downloadUrl = GetDownloadUrl(url, stringFormat) + $"&gid={sheetId}"; 30 | return await DownloadAsyc(downloadUrl); 31 | } 32 | 33 | public static async Task DownloadAsync(string fileName, string sheetUrl, string savePath, FileFormat format) 34 | { 35 | ValidateInputData(fileName, sheetUrl, savePath); 36 | 37 | var stringFormat = GetStringFormat(format); 38 | var directoryPath = $"{Application.dataPath}/{savePath}"; 39 | var finiteSavePath = $"{directoryPath}/{fileName}.{stringFormat}"; 40 | 41 | var downloadUrl = GetDownloadUrl(sheetUrl, stringFormat); 42 | 43 | if (Directory.Exists(directoryPath) == false) 44 | { 45 | Directory.CreateDirectory(directoryPath); 46 | } 47 | 48 | var tableData = await DownloadAsyc(downloadUrl); 49 | await File.WriteAllTextAsync(finiteSavePath, tableData); 50 | } 51 | 52 | private static string GetDownloadUrl(string publicUrl, string format) 53 | { 54 | var match = _regex.Match(publicUrl); 55 | var key = match.Groups[1]; 56 | return $"https://docs.google.com/spreadsheets/export?id={key}&exportFormat={format}"; 57 | } 58 | 59 | private static async Task DownloadAsyc(string downloadUrl) 60 | { 61 | try 62 | { 63 | using var client = UnityWebRequest.Get(downloadUrl); 64 | await client.SendWebRequest(); 65 | if (client.error != null) 66 | { 67 | Debug.LogError(client.error); 68 | { 69 | return null; 70 | } 71 | } 72 | 73 | return client.downloadHandler.text; 74 | } 75 | catch (Exception e) 76 | { 77 | Debug.LogException(e); 78 | throw; 79 | } 80 | 81 | return null; 82 | } 83 | 84 | private static string GetStringFormat(FileFormat format) 85 | { 86 | switch (format) 87 | { 88 | case FileFormat.csv: 89 | return "csv"; 90 | case FileFormat.tsv: 91 | return "tsv"; 92 | case FileFormat.ods: 93 | return "ods"; 94 | default: 95 | throw new ArgumentOutOfRangeException(nameof(format), format, null); 96 | } 97 | } 98 | 99 | private static void ValidateInputData(string fileName, string sheetUrl, string savePath) 100 | { 101 | if (string.IsNullOrEmpty(fileName)) throw new Exception("Name can not be null or empty"); 102 | if (string.IsNullOrEmpty(sheetUrl)) throw new Exception("Download url path can not be null or empty"); 103 | if (string.IsNullOrEmpty(savePath)) throw new Exception("Save path can not be null or empty"); 104 | } 105 | } 106 | 107 | public static class AsyncExtensions 108 | { 109 | public static TaskAwaiter GetAwaiter(this AsyncOperation operation) 110 | { 111 | var tcs = new TaskCompletionSource(); 112 | operation.completed += _ => tcs.SetResult(null); 113 | return ((Task) tcs.Task).GetAwaiter(); 114 | } 115 | } 116 | } -------------------------------------------------------------------------------- /Runtime/GSImporter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3b25161ae47b72f4888f3d181d213937 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.anbi.google-sheet-importer", 3 | "author": "AndreyBirchenko", 4 | "version": "1.0.2", 5 | "displayName": "Unity Google Sheets Importer", 6 | "description": "Unity Google Sheets Importer", 7 | "unity": "2021.3", 8 | "keywords": [], 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/AndreyBirchenko/UnityGoogleSheetsImporter.git" 12 | } 13 | } -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: eff803a320cc3e7499c0ec17aea535a5 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | --------------------------------------------------------------------------------