0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Unityとスプレッドシートを用いてスコア登録をしよう!

Last updated at Posted at 2025-02-06

image.png

流れ

スコアの送信はUnity側からGAS(Google Apps Script)にデータを送り
GASがデータを成型してスプレッドシートに書き込む。

成型といっても先頭に現在時刻を足し、送られてきたデータ順に列を埋めるだけ。
あとハイスコア、つまり送られたデータが二行目のスコア列より高ければ二行目を上書きする。

ハイスコアの受信はその二行目のデータを持ってくるだけで良い。

この流れを楽にするため、送受信するデータの構造体は
String(CSV形式)→構造体と構造体→String(CSV形式)の関数を作っておく。

Unity

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

/// <summary>
/// スコアデータの管理とGoogleスプレッドシートとの連携を行うクラス
/// </summary>
public class ScoreDataManager : MonoBehaviour
{
    private ScoreData currentScoreData;

    /// <summary>
    /// スコアデータを格納する構造体
    /// </summary>
    public struct ScoreData
    {
        public string name;
        public int score;
        public int shotCount;
        public List<string> targetHitRate;

        public ScoreData(string name, int score, int shotCount, List<string> targetHitRate)
        {
            this.name = name;
            this.score = score;
            this.shotCount = shotCount;
            this.targetHitRate = targetHitRate;
        }

        /// <summary>
        /// CSVデータからスコアデータを生成
        /// </summary>
        public ScoreData(string data)
        {
            data = data.Replace("\"", "");
            var parts = data.Split(',');
            name = parts[1];
            score = int.Parse(parts[2]);
            shotCount = int.Parse(parts[3]);
            targetHitRate = parts.Skip(4).ToList();
        }

        /// <summary>
        /// スコアデータをCSV形式の文字列に変換
        /// </summary>
        public override string ToString()
        {
            return $"{name},{score},{shotCount},{string.Join(",", targetHitRate)}";
        }
    }

    [SerializeField] private string spreadsheetID = ""; // スプレッドシートのID
    [SerializeField] private string spreadsheetName = ""; // 取得するシート名
    [SerializeField] private string gasUrl = ""; // Google Apps ScriptのURL

    private List<ScoreData> highScoreDataList = new List<ScoreData>();

    /// <summary>
    /// Googleスプレッドシートからスコアデータを取得
    /// </summary>
    private IEnumerator GetData()
    {
        highScoreDataList.Clear();
        string url = $"https://docs.google.com/spreadsheets/d/{spreadsheetID}/gviz/tq?tqx=out:csv&sheet={spreadsheetName}";

        using (UnityWebRequest req = UnityWebRequest.Get(url))
        {
            yield return req.SendWebRequest();

            if (req.result == UnityWebRequest.Result.Success)
            {
                string[] rows = req.downloadHandler.text.Split(new[] { "\n" }, System.StringSplitOptions.RemoveEmptyEntries);

				// ヘッダー行をスキップして二行目のハイスコア行を取得
                foreach (string row in rows.Skip(1)) 
                    highScoreDataList.Add(new ScoreData(row));
            }
        }
    }
    
    /// <summary>
    /// スコアデータをGoogleスプレッドシートに送信
    /// </summary>
    private IEnumerator PostData()
    {
        WWWForm form = new WWWForm();
        form.AddField("val", currentScoreData.ToString());

        using (UnityWebRequest req = UnityWebRequest.Post(gasUrl, form))
            yield return req.SendWebRequest();
    }
}

GAS

function doPost(e) {
  // スクリプトのロックを取得(同時実行を防ぐため)
  var lock = LockService.getScriptLock();
  lock.waitLock(30000); // 最大30秒待機

  try {
    // Googleスプレッドシートを開く
    //https://docs.google.com/spreadsheets/d/ ここを /edit?gid=0#gid=0
    var ss = SpreadsheetApp.openById(ここに);
    var sheet = ss.getSheetByName("シート(ページ)名");

    // POSTされたデータを取得
    // parameter."val" は 自分でUnity側から送った名前
    var val = e.parameter.val.split(","); // カンマ区切りのデータを配列に変換

    // 先頭に現在の日時を追加(記録時刻)
    val.unshift(new Date());

    // スプレッドシートの既存データを取得して最高スコアを保存する
    var data = sheet.getDataRange().getValues(); // 全データ取得
    if (data.length >= 2) { // 念のため2行目が存在するか確認
      var highScore = parseFloat(data[1][スコアが保存される列]); // 2行目のスコア
      var newScore = parseFloat(val[スコアが保存される列]); // 新しいスコア

      if (!isNaN(highScore) && !isNaN(newScore) && newScore > highScore) {
        // 新しいスコアの方が大きければ2行目を上書き
        sheet.getRange(2, 1, 1, val.length).setValues([val]);
      }
    }

    // 新しい行を追加
    sheet.appendRow(val);
    return ContentService.createTextOutput("Success").setMimeType(ContentService.MimeType.TEXT);

  } catch (error) {
    // エラー処理
    Logger.log(error.toString());
    return ContentService.createTextOutput("Error: " + error.toString()).setMimeType(ContentService.MimeType.TEXT);
  } finally {
    // 入力ロック解除
    lock.releaseLock();
  }
}
0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?