GSheet is a plugin that converts game design data written in Google Sheets into C# types and binary data ready for use in Unity.
Data created in Google Sheets can be used in both the Editor and at runtime.
Downloaded data automatically generates types, allowing you to access values via Gsheet.Instance.
Managing game design data in Google Sheets and integrating it with Unity is a very common pipeline in the industry. However, due to the lack of an official plugin, each project had a different implementation with varying functional limitations. This plugin was developed to consolidate the core features required in real live-service development and maximize productivity.
- Change Diff Viewer
- Provides a
DiffViewerto visually inspect data changes by comparing the downloaded data against the previous version.
- Provides a
- LWSerialize (High-Performance Serialization Library)
- Uses a DirectMemoryCopy-based serialization library to dramatically reduce data size and improve load speed.
- Unity DOTS Support
- Supports formats such as
NativeContainerandFixedStringfor ECS architecture.
- Supports formats such as
- List / Dictionary / struct / class Options
- These keywords can be configured when structuring Google Sheet data.
- High Extensibility
- Supports array types and user-defined types (CustomType).
- Any type implementing the
IGSheetParserinterface can be used.
- Localization Support
- Provides localization functionality using Google Sheets.
TextMeshProLocalizeUGUIoffers multi-language support and font mapping for TextMeshPro.LocalizeStringreturns a string according to the currently configured language.
Settings are located at Assets/Resources/GsheetSetting.asset by default. If the asset does not exist, it will be automatically created on script reload.
The main configuration options are as follows.
| Field | Description |
|---|---|
Code Generation Path |
The path where generated C# code will be saved. Default is Scripts/Generator. |
Sheet ID |
The /d/{spreadsheetId}/ portion of the Google Spreadsheet URL. |
Localize Setting / Sheet Name |
The sheet name to use as localization data. e.g. Localize |
Localize Setting / Font Sets |
TMP font mapping per language. |
If Code Generation Path in the settings asset is Scripts/Generator, the namespace of the generated code will be Generator.
In cell A1 of each sheet, write the type to be generated.
This value is used as the class / struct keyword for the generated sheet type.
Declare fields in each column of the first row using the following format.
| struct | string name | int hp | Vector3 pos | Color color | int[] rewards |
|---|---|---|---|---|---|
| unit_100 | Soldier | 100 | 0.2,0.11 | #0000FF | 1,2,3 |
| unit_101 | Archer | 70 | 1.22,-5 | #FF0000 | 2,2,6 |
Since the first column may be used as the data key, actual data fields are generated starting from the second column.
If a data row has a value in the first column, the sheet is generated as Dictionary<string, SheetType>.
| class | string name | int hp |
|---|---|---|
| unit_100 | Soldier | 100 |
| unit_101 | Archer | 70 |
Generated result:
public static Dictionary<string, Unit> Unit => Instance._Unit;If the first column is empty, the sheet is generated as List<SheetType>.
| class | string name | int hp |
|---|---|---|
| Soldier | 100 | |
| Archer | 70 |
Generated result:
public static List<Unit> Unit => Instance._Unit;- If an entire row starts with
//, it is treated as a comment row and ignored. - If a column header in the first row starts with
//, that entire column is ignored.
The following types are available with the default implementation.
- C# primitives:
int,float,long,bool, etc. string- enum
- Arrays:
int[],string[], etc. - Unity types:
Vector2,Vector3,Vector2Int,Vector3Int,Color - DOTS / Unity.Collections types:
NativeArray<T>NativeReference<T>FixedString32BytesFixedString64BytesFixedString128BytesFixedString512BytesFixedString4096Bytes
- Custom types that provide a parsing method via
IParserFormatterorIGSheetParser - User-defined types that support binary serialization via
ILwSerializable
Arrays and NativeArrays decompose the internal string using StringArray.Convert and re-parse each element with the appropriate type formatter.
The following items are available from the Unity top menu.
| Menu | Description |
|---|---|
Tools/- Gsheet -/Generate |
Downloads the Google Sheet, saves binary data, and runs code generation. |
Tools/- Gsheet -/View GoogleSheet |
Opens the currently configured Google Sheet in a browser. |
Tools/- Gsheet -/View Setting |
Opens the GsheetSetting Inspector window. |
Tools/- Gsheet -/View Log-Diff |
Opens the Diff Viewer to inspect data changes before and after generation. |
On successful generation, the following files are updated.
Assets/Resources/GsheetData.bytes
Assets/Scripts/Generator/GSheet.cs
Assets/Scripts/Generator/{SheetName}.cs
The last generation info is displayed in LastUpdateInfo in the GsheetSetting Inspector.
Generated data is accessed via the static properties of the Gsheet class.
using Generator;
using UnityEngine;
public class UnitSample : MonoBehaviour
{
private void Start()
{
var unit = Gsheet.ExampleStruct[Gsheet.UNIT_100];
Debug.Log(unit.speed);
foreach (var item in Gsheet.ExampleClass)
{
Debug.Log(item.localizeName);
}
}
}When Gsheet.Instance is first accessed, it reads Resources/GsheetData.bytes and restores all sheet data.
Keys for sheets generated as Dictionary are also generated as constants in the Gsheet partial class.
Gsheet.UNIT_100
Gsheet.UI_OKSpecify the localization sheet name in Localize Setting / Sheet Name within GsheetSetting.asset. The current sample configuration uses the Localize sheet.
The localization sheet uses the first column as the key and subsequent column names as language codes.
class,string EN,string KR,string JP
ui_ok,OK,확인,確認
ui_cancel,Cancel,취소,キャンセル
On generation, LangCode.cs is updated to match the language columns of the localization sheet.
To change the language in code, use LocalizeManager.
using SheetData;
using SheetData.Localize;
LocalizeManager.Instance.SetLanguage(LangCode.KR);To retrieve a string directly, use the following.
string text = LocalizeManager.Instance.Localize(Gsheet.UI_OK);The TextMeshProLocalizeUGUI component holds a LocalizeString key and automatically updates its text and font whenever the language changes.
To convert a sheet string into a custom type, implement IGSheetParser. Since IGSheetParser requires both IParserFormatter and ILwSerializable, you must provide both a string parsing method and a binary serialization method.
using LWSerializer;
using SheetData.IO;
using SheetData.Scripts.Parsing;
public class CustomClass : IGSheetParser
{
private string _unitName;
private int _unitNumber;
public object ToData(string content)
{
var datas = StringArray.Convert(content);
return new CustomClass
{
_unitName = datas[0],
_unitNumber = int.Parse(datas[1])
};
}
public void Write(string content, SheetBinaryWriter writer)
{
writer.Write((CustomClass)ToData(content));
}
public void OnNativeWrite(LwBinaryWriter writer)
{
writer.Write(_unitName, _unitNumber);
}
public void OnNativeRead(LwBinaryReader reader)
{
reader.Read(out _unitName, out _unitNumber);
}
}If the parser type and the actual target type differ, you can use ParserTriggerAttribute.
[ParserTrigger(typeof(MyTargetType))]
public class MyTargetTypeFormatter : IParserFormatter
{
public object ToData(string content)
{
// Convert string to MyTargetType
}
public void Write(string content, SheetBinaryWriter writer)
{
writer.Write((MyTargetType)ToData(content));
}
}- Set the Google Sheet ID and code generation path in
Assets/Resources/GsheetSetting.asset. - Run
Tools/- Gsheet -/Generatefrom the Unity menu. - The plugin refreshes each sheet name and gid from Google Sheets.
- Each sheet is downloaded as a CSV.
- The first row header is read to interpret type information.
- Sheet data is saved as binary to
Assets/Resources/GsheetData.bytes. - Per-sheet types and
Gsheet.csare generated underAssets/Scripts/Generator. - At runtime, the
Gsheetsingleton reads the binary viaResources.Load<TextAsset>and restores the data.
Records of Add, Remove, and Insert operations that occurred during the last generation are displayed.
Note that comparison for objects implementing IDisposable (such as NativeArray) is not supported.
- Google Sheets must be set to public or have appropriate sharing permissions accessible from the Editor. (Sharing with anyone who has the link is recommended.)
- Fields that require disposal, such as
NativeArray<T>andNativeReference<T>, are cleaned up in the generated type'sDispose(). If you implementDisposein a custom type, make sure to also implement theIDisposableinterface. - Extend generated code by writing additional logic in a separate
partial classfile.
The project's default configuration points to the following sample Google Sheet.
https://docs.google.com/spreadsheets/d/1188AKPfAl2taqn6G-JDENJF-WeO_YA_gE4SRYzMRZBc/edit
URL for Unity Package Manager
https://github.com/eowns9753/Gsheet.git?path=Assets/Plugins/GSheet