さけのさかなのブログ

同人ゲーム開発やってます。Unity使ったりする。

【Unity】Googleスプレッドシートの値を取得する・2

やること

 非公開設定のスプレッドシートからセルの内容を読み込む

 環境:Unity2019.2.17、UniTask、Utf8Json

参考:前の記事

toriden.hatenablog.com

手順

1. クライアントID、クライアントシークレット発行

 GoogleCloudPlatformでクライアントIDとクライアントシークレットを作る

2.コード

    async void Start()
    {
        // リフレッシュトークンがない場合は認証してリフレッシュトークンを取得し、保存しておく
        var client = "クライアントId";
        var secret = "クライアントシークレット";
        var scope = "https://www.googleapis.com/auth/spreadsheets.readonly";
        var refreshToken = await GoogleApi.RequestRefreshToken(scope, client, secret);

        // リフレッシュトークンからアクセストークンを取得
        var accessToken = await GoogleApi.RequestAccessToken(refreshToken.refresh_token, client, secret);

        // スプレッドシート取得
        var sheetId = "シートId";
        var sheet = await GoogleApis.SpreadSheet.LoadByAccessTokenAsync(accessToken.access_token, sheetId, "シート1");
        Debug.Log(sheet.JsonString);
    }

 リフレッシュトークンを保存する際には暗号化をかけておきましょう。

 Windows環境のみ対応。スマホアプリの場合、認証処理はリダイレクト処理をURIスキーマ経由にすることでうまくいく(はず)。Macは知らない

ひっかかりどころ

 認証時に警告が出たりします。

www.eripyon.com

リポジトリ

github.com

参考

github.com

【Unity】雑にUtf8Json

 Utf8JsonでDictionary<string, object>とかをガッとシリアライズできるようにします。

初期化

Utf8Json.Resolvers.CompositeResolver.RegisterAndSetAsDefault(
    new[] { Utf8Json.Formatters.PrimitiveObjectFormatter.Default },
    new[] {
        Utf8Json.Resolvers.GeneratedResolver.Instance, // 作ってないなら要らない
        Utf8Json.Resolvers.BuiltinResolver.Instance,
        Utf8Json.Resolvers.DynamicGenericResolver.Instance
    });

バグ

 現在のunitypackage(1.3.7)にはバグがあります。

 たとえばこんなコード。

var obj = new Dictionary<string, object> { {"hoge", new [] { 1, 2, 3 } } };
var jsonString = Utf8Json.JsonSerializer.ToJsonString(obj);
Debug.Log(jsonString); // -> {"hoge":[123]}

 Json文字列の配列にカンマが抜けてますね。

 ↓の修正を反映しましょう。

github.com

何が雑かというと

 コードジェネレータ使えっていう話ではあるんだけど、一方こういう使い方も許容されてますよという話ですね。

【Unity】古いMiniJsonは使うな

 以下のコードでバグがでる。

System.Globalization.CultureInfo.CurrentCulture = System.Globalization.CultureInfo.GetCultureInfo("fr-FR");
var dict = new Dictionary<string, object>();
dict["hoge"] = 1.5f;
var jsonString = MiniJSON.Json.Serialize(dict); // {"hoge":1,5} 不正なJson文字列が吐き出されて
MiniJSON.Json.Deserialize(jsonString); // 解釈に失敗。エラー!

 CurrentCultureなんていじらねーよ!と思うかもしれませんが、OSがフランス語設定だと同じ現象が起こります。

原因

 小数点表記がカルチャ依存になっていることに由来する。

 フランス語圏においては小数点はカンマでなので、MiniJsonはそれにひっぱられて↑のコードだと{"hoge":1,5}というJsonを吐き出す。

 一方でJsonの規格は小数点をドットで統一しているので、このJson文字列は不正なものとなる。なんとMiniJson自身でも解釈に失敗する。

対応

 おとなしくモダンなJsonリアライザつかいましょう。

 どうしてもというなら、修正版があってこっちでは直ってるっぽい。 github.com

 (CurrentCultureをインバリアントカルチャにいちいち設定してやる、というのは思いつくんですが、スレッドごとの指定だとか、影響範囲がわからん、とかでリスキーかと)

docs.microsoft.com

ついでに

float.Parsefloat.ToStringもウカツに使うとアカンという話でもあり。

こわいね

 国内リリースでは機嫌よく動いてたゲームが海外に出すと動かん、みたいなのはこういうところが原因だったり。

続き

toriden.hatenablog.com

【Unity】UIをキーボードから操作するサンプル

github.com

 なんかの拍子に「マウスとキーボード両対応したい」みたいになった時にウチはこんなのを組んでますというやつ。

 別にそんなん要らん…という場合でも、「右クリックを閉じるボタンに割り当てる」というのも仕組みとしては同じなので、組んでおくとわりと操作性がよくなったりします。

 大まかな仕組みとしては、たとえばEnterキーが押されたらUI表示を上から順に探し、キーがバインドされてるボタンが見つかったらInvokeするという感じ(ざっくり)。実際はさらに方向キーによるカーソル移動やらUIのリンク処理やらメンドクサイあれこれを書いてやる必要がある。

 CursorControllerUtil.csあたりの書き殴り感がひどいのでアレですが、あの辺こそが秘伝ソース的奥儀的だったりするわけだ。(そのうち綺麗に書けるようになったりしろ)

 というか、なんか似たようなことをしてくれる既存アセットはないんすか。

【Unity】アツマールにUnityWebGLをアップロードするときの画面サイズ対応

やること

 UnityWebGLビルドをRPGアツマールにアップロードした場合、そのままだと画面サイズが固定になってスマホで遊べない。のでその対応。

index.htmlの書き換え

 bodyタグを以下のようにする。0.75というのがアスペクト比4:3の数値。

  <body>
    <div id="unityContainer" style="width: 100%; height: calc(100vw * 0.75);"></div>
  </body>

参考

[css]アスペクト比を固定して可変させる方法 ~よく見る75%ってなに!?~|blog(スワブロ) | スワローインキュベート

前記事

toriden.hatenablog.com