├── .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 |
26 |
27 | Нажмите **Add** чтобы добавить новую таблицу.
28 |
29 |
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 |
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 |
26 |
27 | Click **Add** to add a new table.
28 |
29 |
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 |
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