Skip to content

Instantly share code, notes, and snippets.

@thebeardphantom
Last active October 29, 2023 10:35
Show Gist options
  • Save thebeardphantom/80ec92b78abf240d0d4119cf9a719f74 to your computer and use it in GitHub Desktop.
Save thebeardphantom/80ec92b78abf240d0d4119cf9a719f74 to your computer and use it in GitHub Desktop.
Simple .gsheet to TextAsset ScriptedImporter for Unity, with code from https://gist.github.com/jasonleehodges/359eb2af0d1caec0153bb7450c165ffd
[ScriptedImporter(1, "gsheet")]
public class GSheetImporter : ScriptedImporter
{
#region Types
private class WebClientEx : WebClient
{
#region Fields
private readonly CookieContainer _container;
#endregion
#region Constructors
public WebClientEx(CookieContainer container)
{
_container = container;
}
#endregion
#region Methods
protected override WebRequest GetWebRequest(Uri address)
{
var r = base.GetWebRequest(address);
if (r is HttpWebRequest request)
{
request.CookieContainer = _container;
}
return r;
}
protected override WebResponse GetWebResponse(WebRequest request, IAsyncResult result)
{
var response = base.GetWebResponse(request, result);
ReadCookies(response);
return response;
}
protected override WebResponse GetWebResponse(WebRequest request)
{
var response = base.GetWebResponse(request);
ReadCookies(response);
return response;
}
private void ReadCookies(WebResponse r)
{
if (r is HttpWebResponse response)
{
var cookies = response.Cookies;
_container.Add(cookies);
}
}
#endregion
}
[Serializable]
private class AdditionalSheet
{
#region Properties
[field: SerializeField]
public string Name { get; private set; }
[field: SerializeField]
public int Gid { get; private set; }
#endregion
#region Constructors
public AdditionalSheet(string name, int gid)
{
Name = name;
Gid = gid;
}
#endregion
}
#endregion
#region Properties
[field: SerializeField]
private AdditionalSheet[] Sheets { get; set; }
#endregion
#region Methods
[OnOpenAsset]
private static bool OnOpenAsset(int instanceID)
{
var asset = EditorUtility.InstanceIDToObject(instanceID);
var assetPath = AssetDatabase.GetAssetPath(asset);
if (assetPath.EndsWith(".gsheet"))
{
var docId = GetDocId(assetPath);
var assetImporter = (GSheetImporter)GetAtPath(assetPath);
var sheet = AssetDatabase.IsMainAsset(asset)
? new AdditionalSheet("", 0)
: assetImporter.Sheets.First(a => a.Name == asset.name);
var url = $"https://docs.google.com/spreadsheets/d/{docId}/edit#gid={sheet.Gid}";
Application.OpenURL(url);
return true;
}
return false;
}
private static string GetDocId(string assetPath)
{
var contents = File.ReadAllText(assetPath);
var jObject = JObject.Parse(contents);
var docId = jObject["doc_id"]!.Value<string>();
return docId;
}
/// <inheritdoc />
public override void OnImportAsset(AssetImportContext ctx)
{
var docId = GetDocId(ctx.assetPath);
var textAsset = GetTextAsset(ctx, docId, new AdditionalSheet(Path.GetFileNameWithoutExtension(ctx.assetPath), 0));
ctx.AddObjectToAsset("MainObject", textAsset);
ctx.SetMainObject(textAsset);
foreach (var sheet in Sheets.Where(s => !string.IsNullOrWhiteSpace(s.Name)))
{
textAsset = GetTextAsset(ctx, docId, sheet);
ctx.AddObjectToAsset(textAsset.name, textAsset);
}
}
private TextAsset GetTextAsset(AssetImportContext ctx, string docId, AdditionalSheet sheet)
{
string csvContents;
try
{
var url = $"https://docs.google.com/spreadsheets/d/{docId}/export?format=csv&gid={sheet.Gid}";
using var wc = new WebClientEx(new CookieContainer());
wc.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0");
wc.Headers.Add("DNT", "1");
wc.Headers.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
wc.Headers.Add("Accept-Encoding", "deflate");
wc.Headers.Add("Accept-Language", "en-US,en;q=0.5");
csvContents = wc.DownloadString(url);
}
catch (Exception e)
{
ctx.LogImportError(e.ToString());
csvContents = e.ToString();
}
var textAsset = new TextAsset(csvContents)
{
name = sheet.Name
};
return textAsset;
}
#endregion
}
[CanEditMultipleObjects]
[CustomEditor(typeof(GSheetImporter))]
public class GSheetImporterEditor : ScriptedImporterEditor
{
#region Methods
/// <inheritdoc />
public override void OnInspectorGUI()
{
DrawDefaultInspector();
if (GUILayout.Button("Reload"))
{
SaveChanges();
}
ApplyRevertGUI();
}
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment