GSTU(Google Sheet To Unity)라는 에셋을 통해 실시간으로 시트의 데이터를 불러올 수 있다.
에셋은 무료이니 Sheet를 Json으로 변환한 뒤 가져와서 파싱할 번거로움을 덜어줄 수 있다.
세팅
먼저 에셋을 다운로드 해준다.
https://assetstore.unity.com/packages/tools/utilities/google-sheets-to-unity-73410
Google Sheets To Unity | 유틸리티 도구 | Unity Asset Store
Use the Google Sheets To Unity from Greener Games on your next project. Find this utility tool & more on the Unity Asset Store.
assetstore.unity.com
그 다음 구글 클라우드에 프로젝트를 설정해준다.
https://console.cloud.google.com/
Google 클라우드 플랫폼
로그인 Google 클라우드 플랫폼으로 이동
accounts.google.com


프로젝트 이름은 자신이 알아볼 수 있게 설정해주면 된다. 별로 중요하지 않음

만약 동의화면 구성을 먼저 하라고 한다면 아래 순서대로 기입하면 된다.
- 앱 정보
- 앱 이름 : 만드는 프로젝트 명
- 이메일 : 구글 이메일
- 대상(외부)
- 연락처 이메일
- 완료 및 생성


생성되고 나면 일단 json 다운로드를 해준다. 나중에 클라이언트 비밀번호가 필요하게 될 수도 있으니 구글 드라이브든 어디든 안전한곳에 저장해두자


그 다음 라이브러리로 이동해서 Google Sheets API를 받아준다.

이후 OAuth 화면의 대상부분에서 테스트 사용자를 추가해준다.
이메일을 입력해서 사용자를 추가해주면 된다.
만약 협업중이라면 다른 개발자도 시트에서 데이터를 받아올 수 있게 동료의 이메일도 사용자로 추가해주면 된다.

유니티로 와서 GSTU 패키지를 받아준다.



이제 Window → GSTU → Open Config를 누른 후 CLientId와 보안 비밀번호를 아까 생성했던 데스크탑 클라이언트의 ID와 비밀번호를 입력해준다. 포트는 8080으로 하면 된다.
이후 Conntection을 눌러 연결해준다. (세션이 있으니 하다가 중간에 못불러 온다면 다시 연결 시도 필수)

이 창이 나온다면 연결 성공
유니티에서 사용하기
이제 실제 코드를 써서 시트에 값을 받아오는 작업을 하자
기본 코드는 아래 블로그를 참고했다.
https://bonnate.tistory.com/264
[유니티] 구글 스프레드 시트(엑셀) 연동 3 - 데이터 가져오기
구글 스프레드 시트를 유니티에 연동하여 데이터를 읽어올 수 있습니다. 실제로 스크립트를 이용하여 유니티에서 데이터를 받아오고 이를 활용합니다. 💬 목차 1. [유니티] 구글 스프레드 시트(
bonnate.tistory.com
나는 이 블로그의 코드를 제네릭 클래스로 커스텀해서 다양한 시트의 데이터를 받아올 수 있게 했다.
using GoogleSheetsToUnity;
using System.Collections;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
using UnityEngine.Events;
public abstract class DataReaderBase<T> : ScriptableObject
{
[Header("시트의 주소")][SerializeField] public string associatedSheet = "";
[Header("스프레드 시트의 시트 이름")][SerializeField] public string associatedWorksheet = "";
[Header("읽기 시작할 행 번호")][SerializeField] public int START_ROW_LENGTH = 2;
[Header("읽을 마지막 행 번호")][SerializeField] public int END_ROW_LENGTH = -1;
[Header("스프레드시트에서 읽혀져 직렬화 된 오브젝트")] public List<T> DataList = new List<T>();
public abstract void UpdateStats(List<GSTU_Cell> list);
}
#if UNITY_EDITOR
[CustomEditor(typeof(DataReaderBase<>), true)]
public class DataReaderEditor : Editor
{
protected object targetDataReader;
void OnEnable()
{
targetDataReader = target;
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
GUILayout.Label("\n\n스프레드 시트 읽어오기");
if (GUILayout.Button("데이터 읽기(API 호출)"))
{
var list = targetDataReader.GetType().GetField("DataList").GetValue(targetDataReader) as IList;
list.Clear();
UpdateStats(UpdateMethodOne);
}
}
void UpdateStats(UnityAction<GstuSpreadSheet> callback, bool mergedCells = false)
{
string associatedSheet = (string)targetDataReader.GetType().GetField("associatedSheet").GetValue(targetDataReader);
string associatedWorksheet = (string)targetDataReader.GetType().GetField("associatedWorksheet").GetValue(targetDataReader);
SpreadsheetManager.Read(new GSTU_Search(associatedSheet, associatedWorksheet), callback, mergedCells);
}
void UpdateMethodOne(GstuSpreadSheet ss)
{
var start = (int)targetDataReader.GetType().GetField("START_ROW_LENGTH").GetValue(targetDataReader);
var end = (int)targetDataReader.GetType().GetField("END_ROW_LENGTH").GetValue(targetDataReader);
var list = (targetDataReader.GetType().GetField("DataList").GetValue(targetDataReader) as IList);
list.Clear();
for (int i = start; i <= end; ++i)
{
var rowCells = ss.rows[i];
object[] parameters = new object[] { rowCells };
targetDataReader.GetType().GetMethod("UpdateStats").Invoke(targetDataReader, parameters);
}
EditorUtility.SetDirty(target);
}
}
#endif
해당 클래스를 상속받아 쓰면 된다.
using GoogleSheetsToUnity;
using System;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "Reader", menuName = "ScriptableObject/Item/DataReader")]
public class ItemDataReader : DataReaderBase<ItemData>
{
public override void UpdateStats(List<GSTU_Cell> list)
{
int id = 0;
string name = "";
ItemExtraStatType ability1Type = ItemExtraStatType.None;
float ability1Value = 0;
ItemExtraStatType ability2Type = ItemExtraStatType.None;
float ability2Value = 0;
int itemEffectId = 0;
int synergyId = 0;
ItemGradeType itemGradeType = ItemGradeType.Common;
string iconURL = "";
for (int i = 0; i < list.Count; i++)
{
switch (list[i].columnId)
{
case "ID":
{
id = int.Parse(list[i].value);
break;
}
case "Grade":
{
itemGradeType = Enum.Parse<ItemGradeType>(list[i].value);
break;
}
case "Name":
{
name = list[i].value;
break;
}
case "Ability1":
{
ability1Type = Enum.Parse<ItemExtraStatType>(list[i].value);
break;
}
case "Value1":
{
ability1Value = float.Parse(list[i].value);
break;
}
case "Ability2":
{
ability2Type = Enum.Parse<ItemExtraStatType>(list[i].value);
break;
}
case "Value2":
{
ability2Value = float.Parse(list[i].value);
break;
}
case "ItemEffectID":
{
itemEffectId = int.Parse(list[i].value);
break;
}
case "SynergyID":
{
synergyId = int.Parse(list[i].value);
break;
}
case "IconURL":
{
iconURL = list[i].value;
break;
}
}
}
DataList.Add(new ItemData(id, itemGradeType, name, ability1Type, ability1Value, ability2Type, ability2Value, itemEffectId, synergyId, iconURL));
}
}
상속받아 쓴 ItemDataReader 클래스이다.
...
[Serializable]
public class ItemStat
{
public ItemExtraStatType ItemExtraStatType;
public ItemTriggerType ItemTriggerType;
public float Value;
}
[Serializable]
public class ItemData
{
...
public int Id;
public string ItemName;
public ItemStat Stat1;
public ItemStat Stat2;
public string IconURL;
public int ItemEffectId;
public int SynergyId;
public ItemGradeType ItemGrade;
public ItemEffectData EffectData;
public string SynergyText;
public string EffectText;
...
public ItemData(int id, ItemGradeType itemGradeType, string _name, ItemExtraStatType ability_1Type, float ability_1Value, ItemExtraStatType ability_2Type, float ability_2Value, int itemEffectId, int synergyId, string iconURL)
{
Id = id;
ItemGrade = itemGradeType;
ItemName = _name;
Stat1 = new ItemStat() { ItemExtraStatType = ability_1Type, ItemTriggerType = ItemTriggerType.Always, Value = ability_1Value };
Stat2 = new ItemStat() { ItemExtraStatType = ability_2Type, ItemTriggerType = ItemTriggerType.Always, Value = ability_2Value };
ItemEffectId = itemEffectId;
SynergyId = synergyId;
IconURL = iconURL;
EffectData = default(ItemEffectData);
}
}
시트의 값을 저장할 ItemData이다.

실제 시트의 데이터이다.
보면 ItemData의 멤버 변수와 동일한 식별자를 가진다.
enum이라면 문자 그대로 대소문자 똑같이 써줘야 한다.

ItemDataReader를 SO로 만들었을 때 사진처럼 4개의 입력과 받아오기 버튼이 있을것이다.
시트의 주소는 구글 시트 URL에서 d/와 /edit? 사이에 있는걸 적어주면 된다.

스프레드 시트의 시트 이름은 받아올 데이터가 있는 시트의 이름이다.
시작과 마지막 행 번호는 받아올 데이터가 담겨있는 행 번호이다.
만약 식별자를 1행에 두고 2-15행에 데이터가 있다면 2와 15를 넣어주면 된다.

데이터를 받아오면 위 사진처럼 Data List에 값이 담기게 된다.
이상으로 GSTU 기본 사용법을 마치겠다.
'Unity' 카테고리의 다른 글
| [Unity] 3D 점프 가능 여부 정밀 체크 (3) | 2025.08.11 |
|---|---|
| [Unity] 특정 단어(글자) 색 지정하는법 (1) | 2025.08.11 |
| [Unity] 유니티 기본 강좌 #04 (애니메이션) (4) | 2025.07.25 |
| [Unity] Run Device AVD 목록 표시 오류 해결 방법 (0) | 2025.06.11 |
| [UNITY] Ui Document앞에 게임 오브젝트 렌더링 (0) | 2025.01.04 |


























