4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Unity #3Advent Calendar 2018

Day 5

SpreadSheetの複数のシートをマスターデータして使う

Posted at

前提

1つのシートをUnityで取得するのは、SpreadSheetのデータをcsvで取得すれば良いので簡単。しかし、複数まとめて取得するのはcsvではできなかった。

やったこと

スプレッドシートのデータをMasterDataSet.csに格納します。
スクリーンショット 2018-12-09 2.23.13.png

KeyValue.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace CA2.Data.MasterData
{
	[System.Serializable]
	public class KeyValue{
		public string key;
		public string value;
	}
}
MasterDataSet.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace CA2.Data.MasterData{
    [System.Serializable]
    public class MasterDataSet{
        public List<KeyValue> keyValueList;
        public List<Item> itemList;
    }
}

リポジトリ

メニューのTools > ConvinientToolsでWindowを開いて、AnyTestボタンを押すことで動作を確認することができます。

流れ

  1. GASでシートのデータをJson形式で公開する。
  2. Unity側でJsonUtilityを用いてMasterDataSetに突っ込む

ポイント1 GASでシートのデータをJson形式で公開する。

Loader.gs
var SPREAD_SHEET_ID = "スプレッドシートのIDを入れる";

function onOpen(e){
  var subMenus = [
    {name: "LogMasterData", functionName: "LogMasterData"}
  ];
  var spreadsheet = SpreadsheetApp.getActive();
  spreadsheet.addMenu("Tools", subMenus)
  
}

function logMasterData(){
  var dataJson = JSON.stringify(getAllMasterData(SPREAD_SHEET_ID));
  Logger.log(dataJson);
  Browser.msgBox(dataJson);
}

function doGet(e) {
  var contents= getAllMasterData(SPREAD_SHEET_ID);
  // Jsonをレスポンスとして返す
  return ContentService.createTextOutput(JSON.stringify(contents)).setMimeType(ContentService.MimeType.JSON)
}

var snakeToCamel = function(p){
  //_+小文字を大文字にする(例:_a を A)
  return p.replace(/_./g,
  function(s) {
    return s.charAt(1).toUpperCase();
  }
)}

function getAllMasterData(sheetId){
  var sheets = SpreadsheetApp.openById(sheetId).getSheets();
  var sheetsData = {}
  sheets.map(function(sheet){ // 各シートごとにデータを生成し
    var rows = sheet.getDataRange().getValues();
    // rowsの0インデックス目から2つ取り除き、除いたものを返す
    var keys = rows.splice(0, 2)[0]; // 0: カラム名 1: コメント
    var sheetData = rows.map(function(row) {
      var obj = {}
      row.map(function(item, index) {
        obj[keys[index]] = item;
      });
      return obj;
    })
    sheetsData[snakeToCamel(sheet.getName()) +"List"] = sheetData;
  })
  return sheetsData;
}


(1) getSheets()を使うと全てのシートを取得することができる。
(2) MasterDataSetの変数名と一致させる

ポイント2 Unity側でJsonUtilityを用いてMasterDataSetに突っ込む

MasterDataLoader.cs
using System;
using System.Collections;
using System.Collections.Generic;
using CA2.Data.MasterData;
using UniRx;
using UnityEngine;

namespace CA2.Data {
	public class MasterDataLoader {
		public IObservable<MasterDataSet> Load (string url) {
			return ObservableWWW.Get (url, null, new ProgressLogger())
				.Do(t => Debug.Log(t))
				.Select (x => {
					try {
						return JsonUtility.FromJson<MasterDataSet> (x);
					} catch (System.Exception) {
						throw;
					}
				});
		}

		public class ProgressLogger : IProgress<float> {
			public void Report (float value) {
				Debug.Log (value);
			}
		}
	}
}

適切な形でJsonをもらえればJsonUtilityで簡単にデータを格納することが可能。

KeyValue.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace CA2.Data.MasterData
{
	[System.Serializable]
	public class KeyValue{
		public string key;
		public string value;
	}
}

KeyValueのvalueは本当はobject型にしたかったのですが、JsonUtilityで値が入らなかったのでstringにしています。

まとめ

ここからさらにScriptableObjectとして保存した後、AssetBundle化して配信することでいい動きができるんじゃないかと思っています。

スクリプト自動生成、AssetBundle化して配信までを1ボタンでできるようにしていければいいなと思います。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?