G2U4S is an asset that converts game data created in Spreadsheet or Excel to Script or ScriptableObject with one click.
Use G2U if you work with Spreadsheet, and Excel if offline.
- Cooperation with G2U
- Support Spreadsheet and Excel, suitable for both team and personal development
- Convert various game data to Const, Enum and ScriptableObject with one click
- ScriptableObject can reference ScriptableObject, call it “ScriptableObject in ScriptableObject”
- Subenum: New Enum system
- Localization available, see samples
- Platform-independent data format, complete only within Unity
- Source code is included and customize available
- Documents in Japanese and English available.
G2U4S is created for game design, and full of know-how that author has developed games for 10 years.
Let’s enjoy developing games using G2U4S too!
Update April 9, 2020: G2U seems to be discontinued from AssetStore. Please use Excel when using G2U4S (I think that Spreadsheet can also be used if there is a past version of G2U)
目次
Operating environment
Operating environment (I verified) : Unity2018.4.23, Unity2019.4.1
Operating environment : Unity2018.4 LTS, Unity2019.4 LTS
G2U 2.1.13+
Note: Possible to operate only in Excel without G2U. Use G2U in case of Spreadsheet only.
How to use
Enter game data in Spreadsheet or Excel, in the same input format whichever you choose.
In case of Spreadsheet, output CSV with G2U. You do not have to do this if in Excel.
Convert CSV or Excel to Script or ScriptableObject with “Tools / G2U4S”.
Change settings in G2U4S.xlsx
The G2U4S configuration file “G2U4S.xlsx” is located directly below the asset. G2U4SConst is a class manages setting value, and G2U4SEnum is an enum used in the program. You can change the behavior of the asset by changing the “Value”.
For your information, this asset itself works with scripts, G2U4SConst and G2U4SEnum, created with G2U4S. At the same time I developed the asset, I also verified it.

Enter game data in Spreadsheet or Excel
Define data type in the top left cell of the sheet. Each data type is converted to Script or ScriptableObject. If you select None, the sheet is ignored.
Const
Constant script, such as “const” and “static readonly”.
GameConst.cs
// Auto-generated files
using G2U4S;
using GAMEST;
using UnityEngine;
using System;
namespace GAMEST
{
/// <summary>
/// Game constant
/// </summary>
public static class GameConst
{
/// <summary>
/// Release flag
/// </summary>
public const bool IsRelease = true;
/// <summary>
/// Application version
/// </summary>
public static readonly string Version = Application.version;
/// <summary>
/// Localized language
/// </summary>
public static readonly SystemLanguage Language = SystemLanguage.English;
}
}
Enum
Enum script, and “Subenum” is an extension method.
GameEnum.cs
// Auto-generated files
using G2U4S;
using GAMEST;
using UnityEngine;
using System;
namespace GAMEST
{
/// <summary>
/// Direction
/// </summary>
public enum Dir : int
{
/// <summary>
/// None
/// </summary>
None = -1,
/// <summary>
/// Up
/// </summary>
Up = 0,
/// <summary>
/// Right
/// </summary>
Right = 1,
/// <summary>
/// Down
/// </summary>
Down = 2,
/// <summary>
/// Left
/// </summary>
Left = 3,
}
/// <summary>
/// Motion
/// </summary>
public enum MotionType : int
{
/// <summary>
/// Idle
/// </summary>
Idle,
/// <summary>
/// Walk
/// </summary>
Walk,
/// <summary>
/// Run
/// </summary>
Run,
/// <summary>
/// Guard
/// </summary>
Guard,
/// <summary>
/// Damage
/// </summary>
Damage,
/// <summary>
/// Normal attack
/// </summary>
NormalAttack,
/// <summary>
/// Special attack
/// </summary>
SpecialAttack,
}
public static partial class G2U4Subenum
{
/// <summary>
/// Idle
/// </summary>
public static bool IsIdle(this MotionType value) { return value == MotionType.Idle; }
/// <summary>
/// Walk
/// </summary>
public static bool IsWalk(this MotionType value) { return value == MotionType.Walk; }
/// <summary>
/// Run
/// </summary>
public static bool IsRun(this MotionType value) { return value == MotionType.Run; }
/// <summary>
/// Guard
/// </summary>
public static bool IsGuard(this MotionType value) { return value == MotionType.Guard; }
/// <summary>
/// Damage
/// </summary>
public static bool IsDamage(this MotionType value) { return value == MotionType.Damage; }
/// <summary>
/// Normal attack
/// </summary>
public static bool IsNormalAttack(this MotionType value) { return value == MotionType.NormalAttack; }
/// <summary>
/// Special attack
/// </summary>
public static bool IsSpecialAttack(this MotionType value) { return value == MotionType.SpecialAttack; }
/// <summary>
/// Move or not
/// </summary>
public static bool IsMove(this MotionType value) { return value == MotionType.Walk || value == MotionType.Run; }
/// <summary>
/// Attack or not
/// </summary>
public static bool IsAttack(this MotionType value) { return value == MotionType.NormalAttack || value == MotionType.SpecialAttack; }
/// <summary>
/// Whether it is possible to attack
/// </summary>
public static bool CanAttack(this MotionType value) { return value == MotionType.Idle || value == MotionType.Walk || value == MotionType.Run || value == MotionType.Guard; }
}
}
ScriptableObject
Single ScriptableObject.
TestData.cs
// Auto-generated files
using G2U4S;
using GAMEST;
using UnityEngine;
using System;
namespace GAMEST
{
/// <summary>
/// Test data
/// </summary>
public class TestData : ScriptableObject
{
/// <summary>
/// Whether it is in test
/// </summary>
public bool IsTest;
/// <summary>
/// World time
/// </summary>
public SerializableDateTime WorldTime;
/// <summary>
/// Motion
/// </summary>
public MotionType Motion;
/// <summary>
/// Weapon ID list
/// </summary>
public int[] WeaponIds;
/// <summary>
/// Collision time range
/// </summary>
public Vector2 CollidableTime;
}
}
LocalizeData.cs
// Auto-generated files
using G2U4S;
using GAMEST;
using UnityEngine;
using System;
namespace GAMEST
{
/// <summary>
/// Localization data
/// </summary>
public class LocalizeData : ScriptableObject
{
/// <summary>
/// Key
/// </summary>
public string[] Keys;
/// <summary>
/// Japanese
/// </summary>
public string[] Japanese;
/// <summary>
/// English
/// </summary>
public string[] English;
}
}
ScriptableObjects
Multiple ScriptableObjects.
WorldData.cs
// Auto-generated files
using G2U4S;
using GAMEST;
using UnityEngine;
using System;
namespace GAMEST
{
/// <summary>
/// World data
/// </summary>
public class WorldData : ScriptableObject
{
/// <summary>
/// ID
/// </summary>
public int Id;
/// <summary>
/// Name key
/// </summary>
public string NameKey;
/// <summary>
/// Map data list
/// </summary>
public MapData[] Maps;
}
}
MapData.cs
// Auto-generated files
using G2U4S;
using GAMEST;
using UnityEngine;
using System;
namespace GAMEST
{
/// <summary>
/// Map data
/// </summary>
public class MapData : ScriptableObject
{
/// <summary>
/// ID
/// </summary>
public int Id;
/// <summary>
/// Name key
/// </summary>
public string NameKey;
}
}
G2U outputs CSV for Spreadsheet
G2U, the editor for importing Google spreadsheet data into Unity, with commentary for starting from scratch
When using G2U, I referenced the above article.
Install G2U and open “Window / Google2u”

Log in to Google
Click “Sign in with Google” to log in to Google.

After login, copy the code and paste it into “OAuth Token” then click “Log In”.

Open “Workbooks / Account Workbooks”

Close the eyes of sheets other than game data

Change “Do Not Export” to “CSV”

CSV is output to Google2uGen folder.
When updating Spreadsheet, click the lower left reload button then click the lower right floppy button to update.

Convert CSV or Excel to Script or ScriptableObject with “Tools / G2U4S”

Skill
Support Spreadsheet and Excel
You can use them as follows,
- Excel for personal development and local environment
- Spreadsheet for team development
You can use standard functions of Excel, such as calculation formula etc, without any problem.
As we use G2U, we can cooperate with Spreadsheet surely.
Flexible type and type addition
Any user-defined types can be used within the same namespace and the namespace can be changed with G2U4S.xlsx / G2U4SConst / YourNamespace.
Other types are as follows.
Type | How to specify |
---|---|
array | normal : value1, value2 struct : (value1, value2), (value3, value4) |
enum | Idle enum name |
ScriptableObject | Empty character, due to be decided by the type name. |
ScriptableObjects | 1 The first column value as the ScriptableObject’s key |
sbyte | 1 |
byte | 1 |
short | 1 |
ushort | 1 |
int | 1 |
uint | 1 |
long | 1 |
ulong | 1 |
char | a |
float | 1.0 |
double | 1.0 |
bool | true 1 ○ See G2U4S.xlsx / G2U4SConst / BoolTrueValues |
string | M4u |
SerializableDateTime | 2019-03-22 00:51 |
Vector2 | 1, 1 Numbers with commas are initialized to 0 if you omit the latter. |
Vector3 | 1, 1, 1 |
Vector4 | 1, 1, 1, 1 |
Rect | 1, 1, 1, 1 |
Vector2Int | 1, 1 |
Vector3Int | 1, 1, 1 |
RectInt | 1, 1, 1, 1 |
Quaternion | 1, 1, 1, 1 |
Color | 1, 1, 1, 1 |
Color32 | 255, 255, 255, 255 |
Also, Type can be added with using “G2U4SUtil.Parse (Type type, string str, bool isArray, string assetDir = “”)”, specifically, add an if branch in “Parse”.
SerializableDateTime

As I wrote in the above article, it was a class originally created for G2U4S.
I think that there are many opportunities to handle time in the game, in fact.
ScriptableObject in ScriptableObject
The greatest strength of G2U4S is that ScriptableObject can reference ScriptableObject.
This makes it possible to refer between data and data, so “data” and “program” can be completely separated, and Const and Enum also support it.
As a result planners and programmers can easily share work.
However there is a point to be careful. If you use AssetBundle, it may be redundantly stored in memory, so you should design for performance.
Subenum
Subenum is an extension of enum by method.
For example, if you have the following enum:

“IsMove” is expanded as follows,
/// <summary>
/// Move or not
/// </summary>
public static bool IsMove(this MotionType value)
{
return value == MotionType.Walk || value == MotionType.Run;
}
It can be used as follows.
var motion = MotionType.Walk;
if(motion == MotionType.Walk || motion == MotionType.Run)
{
// Moving
}
// ↓
if(motion.IsMove())
{
// Moving
}
Treat enum the same way as a class in C#
Originally after writing the above article, I have often tried to extend enum by method, but I felt that there was not much advantage to use because of the following reasons.
- It takes time to define.
- There are more places to fix.
- If I use “using static” of C# 7, I can write shorter without extended method.
However during the development of G2U4S, I thought that if I automatically generate an enum, I should also automatically generate an extended method.
“If I generate them automatically, how about combine multiple enumerators?” I further thought, then this function is completed.
I named it Subenum!
It’s like having a small enum inside an enum.
Advantages | Disadvantages |
---|---|
Reduce the amount of code | The cost to call increases due to extended method |
Improve readability | App size increases |
There is a trade-off but I personally like this function.
Localization support
G2U4S can also support localization.
In fact, I made G2U4S to localize the game I developed personally.
Use it as follows, it is a just example and there might be many other ways.

[SerializeField] SystemLanguage language = SystemLanguage.Japanese;
[SerializeField] LocalizeData localizeData;
[SerializeField] WorldData worldData;
Dictionary<string, string> japanese = new Dictionary<string, string>();
Dictionary<string, string> english = new Dictionary<string, string>();
void Start()
{
var keys = localizeData.Keys;
for(var i = 0; i < keys.Length; i++)
{
japanese.Add(keys[i], localizeData.Japanese[i]);
english.Add(keys[i], localizeData.English[i]);
}
var key = worldData.NameKey;
var worldName = (language == SystemLanguage.Japanese) ? japanese[key] : english[key];
Debug.Log($"worldName = {worldName}");
}
Event: OnInit, OnScriptCreated, OnAssetCreated and OnAssetUpdated
G2U4S is executed in the following sequence, callback is called at the end of each.
Sequence | Description |
---|---|
Init | Initialize the settings of G2U4S.xlsx, ie, create G2U4SConst, G2U4SEnum. G2U4SUtil.OnInit() is called. |
CreateScript | Create scripts for Const, Enum, ScriptableObject, ScriptableObjects. G2U4SUtil.OnScriptCreated() is called. |
CreateAsset | Create ScriptableObject, ScriptableObjects assets. G2U4SUtil.OnAssetCreated() is called. |
UpdateAsset | Update asset values of ScriptableObject and ScriptableObjects. G2U4SUtil.OnAssetUpdated() is called |
If you want to add some processing after execution, you can use these callbacks.
END
I think this is not so powerful honestly, but is an easy-to-use skill.
〜オセロを作りながらゲームのプログラムを学ぼう〜