7080 + 1

ゲームプログラミングの記事を書いてます。

【Blender】頂点カラーのAチャンネルを編集・出力できるようにする【v2.77】

※追記 タイトルが誤解を与えてる気がしたので変更しました。

ふと暇だったのでギルティギアXrdのグラフィック記事を読んでいました。もうだいぶ前の記事ですね。
www.4gamer.net

当時読んだときよりもちゃんと理解出来たので、できそうなところはやってみよう、というのが今回の記事の始まりです。
ですが自分は3Dモデリングが出来ません。ならばBlenderを使って既存のモデルを改造しようと思いました。

頂点ペイント

ギルティギアは頂点カラーに色情報は一切持たせず、陰影判定や輪郭線描画にRGBA全てのチャンネルを使っています。

Blenderには頂点ペイントという機能があり、それを使えばペイントツールを使う感覚で頂点カラーを編集出来ます。
f:id:atori708:20171224070157p:plain

が、そのままではRGBしか編集することができません。
やるとすれば、VertexColorsをアルファチャンネル用として作って編集する方法があります。しかしそれではRGBチャンネルが2つで6チャンネル必要になるので、今回の場合メモリの無駄使いです。(というか頂点シェーダに複数の頂点カラー渡せるんでしょうか?)

ということで、この記事ではタイトルの通り、Blenderで頂点カラーのRGBAチャンネルを編集する方法を紹介します。(ギルティギアではない。まさにギルティ)

アドオンを使う

色々調べていると、Aチャンネルも頂点ペイントで編集出来るアドオンを作ってくれている方がいました。
https://forum.unity.com/threads/vertex-rgba-blender-2-5x.254038/

v2.xと書いてありますが、2.77でも動作を確認できました。
アルファチャンネルをいじれるアドオンと、それをFBXに埋め込むためのアドオン両方必要です。入れ方はリンク先を参照してください。

使い方

まずRGBチャンネル用のVertexColorsを追加します。名前はなんでも良いです。次にアドオンで追加したツールから、[Paint on Alpha]をクリックしてください。(見当たらなかったら上図での左下の+ボタンを押すと出てくると思います)
すると先程作ったVertexColorsの名前に _ALPHA とついたVertexColorsが追加されます。これを同じように編集するだけです。色は彩度0で塗って、白が不透明、黒が透明になります。

適当にこんな感じで塗りました。シンプルに4頂点。
f:id:atori708:20171224071842p:plain

次にエクスポートですが、File->Export->Fbxから出来ます。エクスポートする時のFBXのバージョンは FBX 6.1 ASCII を選択してください。仮にUnityにインポートするときには他の設定もいじったほうが良いですが、他のブログがたくさん紹介してるので割愛します。

Unityで描画してみました。頂点カラーのアルファを見て透過処理するシェーダはデフォルトではない(多分)ので、簡単なものですが必要になります。
f:id:atori708:20171224071911p:plain


アドオンのリンク先によると、4チャンネルを全てバラバラに編集するアドオンもあるみたいです。ギルティギアのようにチャンネルごとに意味の違う値が必要な場合には便利ですね。
今回は以上です。質問、訂正などありましたらコメントからお願いします。

補足

Unityは.blendファイルもそのままインポート出来るので、fbxである必要はないです。

蛇足

まだギルティギアの表現には全然至っていません。きっと出来たら記事書こうかと思います。
この記事とは関係ないですが、ギルティギアを作っているアークシステムワークスの次回作であるドラゴンボールファイターズは、照り返しやリムライト表現が増えてよりリッチになっているっぽいので、またどこかで発表してほしいなあとか思いました!

UnityがCドライブを圧迫する!!

自分のPCの記憶領域は128GBのSSDをCドライブ、2TBのHDDをDドライブという構成になっています。ほとんどのアプリをHDDに入れて、絶対速度がほしいのだけSSDに入れるという運用ですね。

が、特に新しいアプリを入れたわけでもないのにCドライブの容量が残り10GBを切って動作が不安定になっていました。んん?となって色々調べた結果、Unityに原因があることがありました。

Cドライブの容量が謎に減っているときは、以下の方法が役に立つかもしれません。

原因その1 UnityのAssetStoreからダウンロードしたパッケージ

AssetStoreからダウンロードすると、UnityPackageはどこに保存されるのでしょうか?特に設定をしていない場合は、Cドライブに保存されます。3Dモデルとかのアセットだと、中にはかなり大きいものもあるので、あっという間に容量を喰らい尽くすことに...(私の場合3GB使ってました...)
その場合は以下の方法が役に立ちます。
unitygeek.hatenablog.com

原因その2 GICache

GIのキャッシュはデフォルトではCドライブに設定されています。GIキャッシュは知らない内にあっという間に膨れ上がる可能性があります。自分の場合は2GB使われていました。3Dゲーム作ってないのに恐ろしや...

これを解決する方法は以下です。
https://docs.unity3d.com/jp/540/Manual/GICache.html

保存されている場所のフォルダを一応削除、あるいは新しいところに移動してからパスを変更することをおすすめします。

補足

上記の原因で気づいた方がいるかもしれませんが、ユーザフォルダのAppData以下にアプリのデータは保存されます。Unityにかぎらず他のアプリもデフォルトだとここにボンボン保存していくみたいなので、
ちゃんと解決してやれば、さらにCドライブの容量を増やせるかもしれません。(自分の場合Chromeが6GBくらい保存してました。)

今回の記事は以上です。
他にもUnity関連で原因がありそうだったら追加していきます。質問やこういうのもあるよってあれば、コメントで教えていただければと思います。

【Unity】ビットマップフォントをUnityで扱う その2【ShoeBox】

前回の続きです。ブログの更新頻度が爆上がりしてます(前年比)
7081.hatenablog.com

ここからはUnity上での作業...といいたいんですが、実は吐き出したxmlファイルをそのまま使おうとするとエラーが出ます。
ので、先にxmlファイルを編集します。

<font>
	<info face="D:\Desktop
umberfont-export" size="35" />
	<common lineHeight="35" scaleW="137" scaleH="141" pages="1" />
	<pages>
		<page id="0" file="D:\Desktop
umberfont-export.png" />
	</pages>
	<chars count="12">
		<char id="53" x="105" y="53" width="29" height="50" xoffset="0" yoffset="-10" xadvance="33" /><!-- 5 -->
		<char id="54" x="37" y="46" width="34" height="50" xoffset="0" yoffset="-15" xadvance="38" /><!-- 6 -->
		<char id="55" x="72" y="91" width="31" height="44" xoffset="0" yoffset="-10" xadvance="35" /><!-- 7 -->
		<char id="56" x="72" y="45" width="32" height="45" xoffset="0" yoffset="-10" xadvance="36" /><!-- 8 -->
		<char id="57" x="0" y="46" width="36" height="49" xoffset="0" yoffset="-10" xadvance="40" /><!-- 9 -->
		<char id="48" x="0" y="0" width="45" height="45" xoffset="0" yoffset="-9" xadvance="49" /><!-- 0 -->
		<char id="49" x="80" y="0" width="17" height="44" xoffset="0" yoffset="-9" xadvance="21" /><!-- 1 -->
		<char id="50" x="46" y="0" width="33" height="44" xoffset="0" yoffset="-9" xadvance="37" /><!-- 2 -->
		<char id="51" x="105" y="0" width="31" height="52" xoffset="0" yoffset="-9" xadvance="35" /><!-- 3 -->
		<char id="52" x="0" y="96" width="36" height="44" xoffset="0" yoffset="-9" xadvance="40" /><!-- 4 -->
		<char id="32" x="0" y="0" width="0" height="0" xoffset="0" yoffset="0" xadvance="22" /><!--   -->
		<char id="9" x="0" y="0" width="0" height="0" xoffset="0" yoffset="0" xadvance="176" /><!-- 	 -->
	</chars>
	<kernings count="0">
	</kernings>
</font>

xmlファイルの中身です。参照するpngファイルのパスが明らかにおかしいですね。2箇所おかしいです。

D:\Desktop
umberfont-export

謎の場所に改行が入っています。(今回の画像はデスクトップに保存していました)
ShoeBoxで出力する際、ファイル名は設定をいじっていなければ「numberfont-export」になります。で、一番最後の\が何故かメタ文字扱いになってしまい、\nになって改行コードになってしまうみたいです。この辺ぶっちゃけよくわかりません。
とりあえず2箇所おかしくなっているので、正しいファイルパスに書き換えてください。

ここからはUnityでの作業です。ShoeBox Tools for Unityをインポートしてからの作業になります。

Asset->ShowBox Tools->Import Bitmap Fontを選択、xmlを選んでください。
エラーとかが出なければ、Asset直下にfontsettingsとマテリアルが出来ます。

あとはuGUIのTextのFontのところに出来たfontsettingsを突っ込めばOKです。
こんな感じになるはずです。
f:id:atori708:20171203021940g:plain
GIFのレコーダーのせいか画像汚いですが、Unity上ではきれいに出てます。

補足

このままだと改行がうまく効かないと思います。fontsettingsのLineSpacingをいい感じの数値にしてください。今回の画像の場合は50くらいがいいかと思います。
あと一行目からなんか文字が出る高さがおかしくなることがあります。これはfontsettingsのCharacterRecsts配列のVertのyで変わってきます。ここはShoeBoxのTxt Line Heightが影響してくるようです。ShowBoxで出力する際の文字出力イメージを見ながらいい感じに調整してください。今回の画像の場合、Txt Line Heightを35くらいにしました。
fontsettingsの値の詳細は面倒くさいのでに他に譲ります。

今回はこれで以上です。不明点や指摘などありましたらコメントでお願いします。

【Unity】ビットマップフォントをUnityで扱う その1【ShoeBox】

今回は長くなったので2回に分けます。
UnityでUIのテキストを表示するときは、uGUIのTextを使うと思います。
(TextMeshProのTextもありますが、オリジナルのビットマップフォントを扱う方法が見つからなかったので割愛)

しかしフォントを使って文字を描画するよりも、自分で作った画像をテキストで表示したいときがあると思います。
特にダメージとかの数字は自分で作った数字画像、つまりビットマップフォントが扱えるとうれしいですね。
Unityではビットマップフォントをサポートしていますが、設定を手動でやる場合、0~9の数字を用意するだけでも結構面倒くさいです。

少しでも楽するためのツールとして、ShoeBoxというものがあったので使い方を紹介します。

・用意するもの
自作の文字画像を1枚にまとめたもの(今回は0~9の数字)
ShoeBox http://renderhjs.net/shoebox/
ShoeBox Tools for Unity https://www.assetstore.unity3d.com/jp/#!/content/35760
※ShoeBoxはAdobeAirで動作しているので、AdobeAirを先にインストールしておく必要があります。

今回はこちらの画像を使います。拾い物。
f:id:atori708:20171202151509p:plain

手順

ShoeBoxを起動すると、タブがSpritesを選んだ状態になってると思います。GUIタブを選んで、BitmapFontのところに画像をD&Dしてください。
新しく開いたウィンドウのSettingsを選ぶと、また新しいウィンドウが開きます。それのAdvancedタブを選択。するとこんな画面になると思います。
f:id:atori708:20171202152442p:plain
設定を以下のように変えてください。

・TemplateをFNT-xml Starlingに(FNT Unityってあるけど無視!!)
・下の方のTxt Charsを「5678901234」に(あとで解説)

一応これで最低限の設定はできてます。
他の項目に関してはこの記事の最後に補足程度に説明しておきます。

Txt Charsをこのように設定したのは、今回扱う画像の並びが「5687901234」になっているからです。
ShoeBoxは文字の形を認識してどの文字を使うか決定しているわけではなく、左上から画像の区切りを1つずつ認識しているだけです。
それぞれにどの文字を当てはめるかを決めるのがTxt Charsです。

Applyを押すと、以下のようになると思います。
f:id:atori708:20171202155659p:plain
上の画像が元画像、左下が完成画像、右下が文字を並べたらどうなるかを見れるところです。
が、なんだか正しく認識できてないっぽいですね。この場合、元画像の数字の間隔をいじってください。ShowBoxを開いたまま画像をいじって、SettingsウィンドウのApplyを押せば読み込み直してくれます。
今回は5~9を少し上にするだけで済みました。

きれいに出来るとこうなります。
f:id:atori708:20171202154828p:plain

思った通りになっていればSave Fontを押してください。元画像があった場所にpngxmlファイルが作られます。
できたファイルをUnityに入れるのが次のステップですが、長くなったので記事を2つに分けます。次回更新までお待ち下さい。

何か不明点、間違っている点があればご指摘ください。

補足

ShoeBoxの設定で、大体いじるであろう項目の解説をしておきます。
・Kerning~~ ...カーニングに関する設定です。今回は数字だけなのでカーニングはしません。ていうか設定の仕方わかりません。
・Message ...完成画像の横に表示する文字です。どんな感じでフォントが並ぶか見れます。
Tex Power Of Two ...完成画像の幅、高さを2の乗数にするかです。ゲームに使うならTrueのほうがいいかも。
・Txt Line Height ...行の高さです。
・Txt Monospace ...文字同士の間隔を詰めるかです。
・Txt Space Width ...スペース文字の間隔の広さです。
・Txt Tab Size Spaces ...タブ文字の大きさをスペースいくつ分にするかの設定です。2,4,8が主流ですね。

【Unity】ポリゴンの裏表で描画を変える

タイトルの通り、シェーダでポリゴンの裏表を判定する方法を紹介します。
ポリゴンがカメラからみて裏か表かで描画の仕方を変えたいとき、2つの方法があります。
他にも方法があれば教えていただければと思います。

・カリングの設定を変えた2つのパスで描画する
・VFACEセマンティクスでif判定して描画を分ける

今回は裏面と表面で色を変えるだけの超シンプルなシェーダにしました。
どちらも得られる結果は同じです。
f:id:atori708:20171112173019g:plain

Gistを初めて使いました。いいですねこれ。

前者は単純にパスを2つ作り、CullのFrontとBackに変えただけのものになります。
後者はパスは一つで、ピクセルシェーダでVFACEを受け取ってif文で色を変えてます。
VFACEは表なら正数,裏なら負数がかえってくるみたいです。

どちらもシェーダの事が分かれば以外と簡単です。(自分はVFACEの存在を知りませんでした。)

問題は重さなのですが、
前者の方法は2回描画するので普通に描画するより重いですし、
後者はif文使っちゃってるので重いと思います。

どちらがいいかは自分にはわかりません。多分毎回if判定走る後者よりも前者のほうが軽い気がします。
この2つの切り替えはそんなに手間ではないのでどちらも試して軽い方採用するのがいいと思います。

【Unity】イントロ+ループ再生を実装する

またUnityの記事です。今回は難易度低め。

BGMを流すとき、イントロ+ループというのを前提にしたBGMって結構あると思います。
Unityではそれを再生する機能が標準でない(Why?)ので、簡単に出来るのを実装してみました。

必要なものは
・イントロとループで分けたAudioClip

だけです。わざわざ分けるのめんどいですが実装が簡単な分こっちに手間がかかるということで...

ソースは以下です。改良なり再配布なりご自由にどうぞ。
(再生、停止の最低限の機能しかないです)

public class BGMPlayer : MonoBehaviour {

    [SerializeField] AudioClip bgmIntroAudioClip;
    [SerializeField] AudioClip bgmLoopAudioClip;

    AudioSource introAudioSource;
    AudioSource loopAudioSource;

    void Start()
    {
        introAudioSource = gameObject.AddComponent <AudioSource>();
        loopAudioSource = gameObject.AddComponent <AudioSource>();

        introAudioSource.clip = bgmIntroAudioClip;
        introAudioSource.loop = false;
        introAudioSource.playOnAwake = false;

        loopAudioSource.clip = bgmLoopAudioClip;
        loopAudioSource.loop = true;
        loopAudioSource.playOnAwake = false;
    }

    public void PlayBGM()
    {
        if (introAudioSource == null || loopAudioSource == null) {
            return;
        }

        introAudioSource.Play ();
        loopAudioSource.PlayScheduled (AudioSettings.dspTime + bgmIntroAudioClip.length);
    }

    public void StopBGM()
    {
        if (introAudioSource == null || loopAudioSource == null) {
            return;
        }

        if (introAudioSource.isPlaying) {
            introAudioSource.Stop ();
        } else if (loopAudioSource.isPlaying) {
            loopAudioSource.Stop ();
        }
    }
}
解説

インスペクタにイントロとループのAudioClipをそれぞれ設定すれば再生出来ます。
今回のやりかたは、AudioSourceをイントロとループでそれぞれ用意して、イントロの再生が終わった瞬間からループを再生する。
という仕組みになっています。

PlayScheduled()を使うことで、再生を遅延させることができます。AudioSetttings.dspTimeはTime.timeとは別に、オーディオを再生するための正しい時間みたいなものです。
時間指定で音を再生する場合はこれ使ったほうがいいと思います。

別の方法

他の方法として、AudioSourceは1つで、イントロの再生が終わると同時にClipを入れ替えるという方法もありますが、切り替えの瞬間にどうしてもノイズが走ってしまいます。
フレーム単位でしか切り替えられないので当然っちゃ当然なんですが、解決方法イマイチわからず...

一番はAudioSourceもAudioClipも1つだけで、ループを開始してほしい時間を指定すれば動いてくれるスクリプトなんですが、色々試した結果上記の方法が一番実装は楽そうでした。
多分サンプルレートとかも考慮して組まないと駄目な気がします。

蛇足

今回の調べて思ったんですが、Unityのマニュアルとリファレンスの音周りがほとんど翻訳されてないのが軽く衝撃でした。

【Unity】スプレッドシートのデータをスクリプトから取得する【OAuth】

久しぶりの更新です。
仕事柄、最近はUnityばかり触ってます。のでUnityの記事です。

ゲームで使う値をエクセルじゃなくてスプレッドシートで管理したかったので、色々調べました。
全体の流れをメモ代わりに書きますが、詳しく触れていないところはわからないところです。

スプレッドシートにアクセスにするには、2つの方法があります。
Google API Keyを使ってアクセスする
OAuth認証をしてアクセストークンをもらい、それでアクセスする

1つ目はすぐに出来ます。APIKeyさえあればアクセス出来ますが、シートの共有をオンにしておく必要があります。
共有するのが嫌な人はOAuth認証を使いましょう。APIKeyのほうは割愛します。

OAuth認証に必要なもの

OAuth認証によるアクセスでは、以下のものが必要になります。
・OAuthクライアントID
・OAuthクライアントシークレット
OAuth認証コード
・アクセストーク
・リフレッシュトーク
スプレッドシートのID

実際にアクセスするのに必要なのはアクセストークンとスプレッドシートのIDのみです。
アクセストークンを取得するのにOAuth認証コードとクライアントシークレットもしくはリフレッシュトークンが必要になり、
OAuth認証コードやリフレッシュトークンを取得するにはOAuthクライアントIDが必要になります。
結構ややこしい。

注意なのは、アクセストークンには有効期限があり、切れるとそのトークンではアクセスできなくなることです。
その時はリフレッシュトークンを使って、アクセストークンを再発行することになります。
リフレッシュトークンに有効期限はない(多分)ので、どこかに保存しておきましょう。

スプレッドシートのIDは、スプレッドシートのURLの一部になります。
https://docs.google.com/spreadsheets/d/[この部分]/edit#gid=0

手順

OAuthのクライアントIDとクライアントシークレットをAPIConsoleから作る

当たり前ですが、Googleアカウントが必要になります。
Google API Consoleとググるとトップにサイトが出てきます。
そこで認証情報→認証情報を作成→OAuthクライアントの作成を選んでください。

f:id:atori708:20170215001707p:plain

アプリケーションの種類を聞かれるので、その他を選んで、名前は適当につけてください。
これでOAuthのクライアントIDとクライアントシークレットを取得できました。

Unityが登場するのはまだ先です。

OAuthのクライアントIDとScopeから、認証コードを取得する

認証コードを取得するには、クライアントIDとScopeが必要になります。
Scopeは、特定のサービスに、どの権限でアクセスするかを教えるものです。
今回はスプレッドシートの読み書きをしたいので、
https://www.googleapis.com/auth/spreadsheets
がScopeになります。

Scopeの種類は以下に書いてあるので、スプレッドシート以外のサービスにもアクセスできます。
OAuth 2.0 Scopes for Google APIs  |  Google Identity Platform  |  Google Developers

コードを取得するには、
https://accounts.google.com/o/oauth2/v2/auth にクエリをたくさんつけてリクエストを投げます。

クエリは、

?scope=https://www.googleapis.com/auth/spreadsheets
&redirect_uri=http://localhost
&response_type=code
&client_id=OAuthクライアントID

になります。
全部ひとつなぎにしてURL欄に入力してください。

URLが正しく入力できていると以下の画面に飛ぶので、許可を選んでください。
もしGoogleのアカウントにログインする画面に飛んだら、OAuthクライアントを作ったアカウントでログインしてください。

f:id:atori708:20170215001833p:plain

許可を押すとredirect_uriで設定した先へ飛んでいきます。
localhostにしたので何もないですが、URLのcode=~以下がOAuthの認証コードになるので保存しておきましょう。

認証コードからアクセストークンとリフレッシュトークンを取得する

ここからUnityでの作業になります。
UnityのWWWを使って、OAuthからスプレッドシートのアクセストークンをもらいましょう。
https://www.googleapis.com/oauth2/v4/token にフォームデータ付きでリクエストを送信します。

WWWForm form = new WWWForm ();
form.AddField ("code", OAuthの認証コード);
form.AddField ("client_id", OAuthクライアントID);
form.AddField ("client_secret", クライアントシークレット);
form.AddField ("redirect_url", "http://localhost");
form.AddField ("grant_type", "authorization_code");
form.AddField ("access_type", "offline");
form.headers.Add ("Content-Type", "application/x-www-form-urlencoded");
Dictionary<string, string> headers = form.headers;
byte[] rawData = form.data;
WWW www = new WWW ("https://www.googleapis.com/oauth2/v4/token", rawData, headers);

レスポンスはwww.textにJSON形式で入って返ってきます。

こんなJSONが返ってきたら成功です。

{
 "access_token": "アクセストークン",
 "token_type": "Bearer",
 "expires_in": 3600,
 "refresh_token": "リフレッシュトークン"
}

expires_inがアクセストークンの有効期限で、スプレッドシートは1時間のようです。
リフレッシュトークンは数に上限があるそうなので、なるべく同じのを使い続けましょう。

Unityからでなくても、curlコマンドを使うと同じことが出来ます。
その方法は他の人が書いてるので割愛。

アクセストークンからスプレッドシートにアクセスする

このシートのデータを取ってきてみましょう。
テイルズオブベルセリアのキャラです。面白かったです。

f:id:atori708:20170215001651p:plain

ここまで来ると簡単で、
https://sheets.googleapis.com/v4/spreadsheets/スプレッドシートのID/values/取得するセルの範囲?AccessToken=アクセストークン
にPOSTすると、セルの中身がJSON形式で返って来ます。

WWW www = new WWW ("https://sheets.googleapis.com/v4/spreadsheets/スプレッドシートのID/values/取得するセルの範囲?AccessToken=アクセストークン");	

今回はセルの範囲をA1:B4にしました。

{
  "range": "'シート1'!A1:B4",
  "majorDimension": "ROWS",
  "values": [
    [
      "名前",
      "性別"
    ],
    [
      "ベルベット",
      "女"
    ],
    [
      "ライフィセット",
      "男"
    ],
    [
      "ロクロウ",
      "男"
    ]
  ]
}

無事取ってこれたでしょうか。
後はJSONをMiniJSONとか使って保存すればOKですね!

リフレッシュトークンからアクセストークンを取得する

先程も書きましたが、アクセストークンには有効期限があるので、もし切れていたら、リフレッシュトークンを使って再発行する必要があります。
https://www.googleapis.com/oauth2/v4/tokenにリクエストを飛ばすと取得できます。

WWWForm form = new WWWForm ();
form.AddField ("refresh_token", リフレッシュトークン);
form.AddField ("client_id", OAuthクライアントID);
form.AddField ("client_secret", OAuthクライアントシークレット);
form.AddField ("grant_type, "refresh_token");
Dictionary<string, string> headers = form.headers;
byte[] rawData = form.data;
WWW www = new WWW ("https://www.googleapis.com/oauth2/v4/token", rawData);

これで成功していたら、アクセストークンがJSON形式で返ってきます。
アクセストークン期限が切れていなくても再発行可能のようです。
10個くらい連続で取得してみたのですが、全部使えました。

アクセストークンが有効かどうか調べる

有効かどうか、また有効期限も調べられます。

WWW www = new WWW("https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=アクセストークン");

無効だった場合

{
 "error_description": "Invalid Value"
}

※もともと存在しない適当な文字列入れても同じエラーが返ってきます。

有効だった場合(例)

{
 "azp": "247046462806-7efg42ut1tau4n2ku081gn81nebma2ab.apps.googleusercontent.com",
 "aud": "247046462806-7efg42ut1tau4n2ku081gn81nebma2ab.apps.googleusercontent.com",
 "scope": "[]https://www.googleapis.com/auth/spreadsheets[]",
 "exp": "1485228014",
 "expires_in": "3584",
 "access_type": "offline"
}

Unityの記事と言いましたが、認証の仕方は他でも使えると思います。
間違っていたり、質問や不明点がありましたらコメントでお願いします。