Open1
[Unity] GSS連携
グーグルスプレッドシートからデータを取得する
パラメーター調整する際などに非エンジニアでも操作ができるようになるので便利
GSSReceiver
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Linq;
using Cysharp.Threading.Tasks;
namespace Test
{
/// <summary>
/// スプレッドシートから取得したデータをシート単位で任意のスクリプタブル・オブジェクトに値として取り込む
/// </summary>
[RequireComponent(typeof(GSSReader))]
public class GSSReceiver : MonoBehaviour
{
public bool IsLoading { get; set; }
/// <summary>
/// GSS のデータ取得準備
/// </summary>
/// <returns></returns>
public async UniTask PrepareGSSLoadStartAsync()
{
IsLoading = true;
await GetComponent<GSSReader>().GetFromWebAsync();
IsLoading = false;
Debug.Log("GSS データを SO に取得");
}
/// <summary>
/// インスペクターから GSSReader の OnLoadEnd にこのメソッドを追加することで GSS の読み込み完了時にコールバックされる
/// </summary>
public void OnGSSLoadEnd()
{
GSSReader reader = GetComponent<GSSReader>();
// スプレッドシートから取得した各シートの配列を List に変換
List<SheetData> sheetDataslist = reader.sheetDatas.ToList();
// 情報が取得できた場合
if (sheetDataslist != null)
{
// スクリプタブル・オブジェクトに代入
DataBaseManager.instance.charaDataSO.playerParametersList =
new List<BattleCharaDataSO.PlayerParameterData>(sheetDataslist.Find(x => x.SheetName == SheetName.Player).DatasList.Select(x => new BattleCharaDataSO.PlayerParameterData(x)).ToList());
DataBaseManager.instance.charaDataSO.enemyParametersList =
new List<BattleCharaDataSO.EnemyParameterData>(sheetDataslist.Find(x => x.SheetName == SheetName.Enemy).DatasList.Select(x => new BattleCharaDataSO.EnemyParameterData(x)).ToList());
DataBaseManager.instance.charaDataSO.animationParametersList =
new List<BattleCharaDataSO.AnimationParameterData>(sheetDataslist.Find(x => x.SheetName == SheetName.Animation_OPGO).DatasList.Select(x => new BattleCharaDataSO.AnimationParameterData(x)).ToList());
}
}
}
}
GSSReader
using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Events;
using Cysharp.Threading.Tasks;
namespace T8S.Map
{
/// <summary>
/// シート名の登録用
/// </summary>
public enum SheetName
{
None, // 自分の作成したスプレッドシート内のシートの名前を登録します
Player,
Enemy,
Animation,
Animation_OPGO
}
/// <summary>
/// 読み込むシートのデータ群。シートの情報を管理します
/// </summary>
[System.Serializable]
public class SheetData
{
public SheetName SheetName;
public List<string[]> DatasList = new List<string[]>();
}
/// <summary>
/// スプレッドシートのデータを取得してシート別に解析します
/// 解析が終了したら、OnLoadEnd に登録したメソッドを呼び出します
/// 解析結果は SheetData クラスの DatasList 変数からシートごとに取得
/// </summary>
public class GSSReader : MonoBehaviour
{
public string SheetID = "読み込むスプレッドシートのアドレス";
public UnityEvent OnLoadEnd; // この変数にインスペクターからメソッドを登録しておくと、スプレッドシートを読み込み後にコールバックする
[Header("読み込みたいシート名を選択")]
public SheetData[] sheetDatas;
public async UniTask Reload() => await GetFromWebAsync();
public void OnClickReload()
{
Reload().Forget();
}
public async UniTask GetFromWebAsync()
{
// CancellationToken の作成
var token = this.GetCancellationTokenOnDestroy();
// 複数のシートの読み込み
for (int i = 0; i < sheetDatas.Length; i++)
{
// シート名だけ毎回読み込み先を変更する
string url = "https://docs.google.com/spreadsheets/d/" + SheetID + "/gviz/tq?tqx=out:csv&sheet=" + sheetDatas[i].SheetName.ToString();
// Web の GoogleSpreadSheet を取得
UnityWebRequest request = UnityWebRequest.Get(url);
// 非同期処理の処理に加えて CancellationToken の設定を行い、非同期処理をキャンセルした場合には処理が停止するようにセットする
await request.SendWebRequest().WithCancellation(token);
Debug.Log(request.downloadHandler.text);
// エラーが発生しているか確認
bool protocol_error = request.result == UnityWebRequest.Result.ProtocolError ? true : false;
bool connection_error = request.result == UnityWebRequest.Result.ConnectionError ? true : false;
// エラーがある場合
if (protocol_error || connection_error)
{
// エラー表示を行い、処理を終了する
Debug.LogError(request.error);
return;
}
// GSS の各シートごとのデータを List<string[]> の形で取得
sheetDatas[i].DatasList = ConvertToArrayListFromCSV(request.downloadHandler.text);
}
// GSSLoader のメソッドを登録しておいて実行する
OnLoadEnd.Invoke();
}
/// <summary>
/// 取得した GoogleSpreadSheet(GSS) の CSV ファイルの情報を ArrayList 形式に変換
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
private List<string[]> ConvertToArrayListFromCSV(string text)
{
StringReader reader = new StringReader(text);
reader.ReadLine(); // 1行目はヘッダー情報なので、読み込んで何もしないで読み飛ばす
List<string[]> rows = new List<string[]>();
while (reader.Peek() >= 0)
{ // Peek メソッドを使うと戻り値の値によりファイルの末尾まで達しているか確認できる。末尾になると -1 が戻るので、そうなるまで繰り返す
string line = reader.ReadLine(); // 一行ずつ読み込み
string[] elements = line.Split(','); // 行のセルは,で区切られているので、それを分割して1文字ずつの情報が入った配列にする
for (int i = 0; i < elements.Length; i++)
{ // 1文字ずつ取り出す
if (elements[i] == "\"\"")
{
continue; // 取り出した文字が空白である場合は除去
}
elements[i] = elements[i].TrimStart('"').TrimEnd('"'); // 文字の最初と最後にある "" を削除する
//Debug.Log(elements[i]);
}
rows.Add(elements);
}
return rows;
}
}
}