【Unity】AWSの利用料金をaws cliから取得して、Unity(WebGL)で可視化した

#概要・はじめに

表題の通り、毎日気になるであろうAWSの利用料金を取得して、そのデータをUnityで可視化するという記事です。
「可視化」という言葉は、よく聞き慣れた単語です。

ただ、、

**「そもそも可視化ってどういう意味さ？」**

ということで、wikipediaで調べてみると・・・

“*可視化とは、人間が直接「見る」ことのできない現象・事象・関係性を「見る」ことのできるもの（画像・グラフ・図・表など）にすることをいう。*”

ここで有権者に訴えたいのは、可視化は**「見ることのできないものを、見れるようにする。」**という意味では無いということ。
**「見ることができないもの」**は見えないのが当たり前なのだから、それを**「見れるようにする」**というのは、そもそも不可能。

しかし、人間の目で直接見ることはできないけれど、何かファインダーを通せば、真物に近い形で見ることができるよという、
言わば「擬似的」に**「見れるようにする」**するという意味です。

そのファインダーというのが、これまでの代表的なもので言えば、画像・グラフ・図・表だったりします。

しかし、ITの技術が進歩した現在では、前述のような2次元の技術に加えて、3Dソフトや3Dプリンターといった3次元の技術が発展しました。
これらを駆使すれば、そのファインダーの精度を高めることができます。

つまり、これまで2次元では見ることができなかった遠い世界が、3次元の技術によって、より近い距離で、より広い視点で、その世界を見れるようになるということです。(**飛行機・潜水艦の登場が、戦争の在り方・見方・根本を変えたように**)

ということもあって、今回はAWSの利用料金を。要は「カネ」という悪魔の申し子ですね。
普段は数字とグラフでしか見れないAWSの利用料金を、Unityで少しだけ見やすいように、またわかりやすいようにしてみました。


#AWSの利用料金を取得する

の前に、aws cliをインストールしておく必要があります。

* [第1回　AWS CLIをインストール](http://gihyo.jp/admin/serial/01/awscli_diary/0001 "第1回　AWS CLIをインストール")


aws cliを使ってcloudwatchのメトリクスで料金を取得。
jqでタイムスタンプでソートをかけ、最新の1件だけ取得します。
取得したデータはリダイレクションでjsonファイルとして出力。
ファイル名は[ **bill.json** ]としました。

```:bill.sh
#!/bin/bash

aws cloudwatch --region us-east-1 get-metric-statistics \
    --namespace "AWS/Billing" \
    --metric-name "EstimatedCharges" \
    --dimensions "[{\"Value\":\"AmazonEC2\",\"Name\":\"ServiceName\"},{\"Value\":\"USD\",\"Name\":\"Currency\"}]" \
    --period 60 \
    --start-time `date -u -d '3 hours ago' +%Y-%m-%dT%TZ` \
    --end-time `date -u +%Y-%m-%dT%TZ` \
    --statistics "Maximum" \
     | jq '.Datapoints | sort_by(.Timestamp) | reverse | .[0]' > bill.json

cat bill.json

```
```json:bill.json

{
  "Timestamp": "2015-05-11T01:07:00Z",
  "Maximum": 0.13,
  "Unit": "None"
}


```

cronの設定もお忘れずに！

#Unity側の設定

こんな感じで作りました。Unityでの表現については、そんなに難しいものでは無いので、さくっと説明を。

![スクリーンショット 2015-05-11 15.20.30.png](https://qiita-image-store.s3.amazonaws.com/0/67591/496fe854-bae7-0cb7-4009-1c3b10e6e689.png)

床とCubeを作ります。何か適当にAWSっぽいテクスチャを貼っつければそれっぽくなる。

##コインを作る
Cylinderを縮小してゴールドのマテリアルを貼付けてコインっぽくします。そのコインをprefab化して、動的生成されるようにしました。

コインのMassやDragはそれなりに調整。

注意が必要なのは、Cylinderはデフォルトで Capsule Collider(明るい緑の線) が衝突判定として使用されるので、メニューから Component > Physics > Mesh Collider を選択する必要があります。

##スクリプト
動的生成のスクリプトは以下の通りです。これを空のオブジェクトを作成してアタッチします。
ただ、このままだと生成場所が変わらないので、positionに変化を付けて左右に散らすようにしても良いかもしれません。


```js

var coin : Transform;

function Start() {	
}

//Webサイト側から呼び出される関数
function bill(count:Number) {
	for (var i = 0; i < count; i++){
			yield WaitForSeconds(1.0);
			billing();
	}
}

function billing (){
	Instantiate(coin,transform.position,transform.rotation);
}

```
準備が整ったら、WebGLにしてビルドします。


#Webサイト側の設定

上記で、出力された[ **bill.json** ]と同一のディレクトリにWebGLとして出力されたindex.htmlが存在するようして、index.htmlを編集します。

かなり雑に書いたのでお許しを。

まずボタンと現在料金を表示するキャプションを作成します。
`<body></body>`内の適当な位置に、下記を追記しました。


```html

<center>
        <p class="cpt">現在の利用料は、$*******です（※コイン一枚につき$0.01)</p>
        <button class="btn">料金を見る</botton>

</center>

```

JSONを扱う為にJQueryを読み込みます。

```html

<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>

```

`</body>`直前の`<script></script>`タグ内に以下のスクリプトを追記します。(かなり雑です。すんません。)

```js

s = document.querySelector("button");

s.addEventListener("click", function() {

  // jsonの読み込み
  $.getJSON("bill.json" , function(data) {
    
    // キャプションの置き換え
    document.querySelector(".cpt").innerHTML ="現在の利用料は、$"+data.Maximum+"です（※コイン一枚につき$0.01）";
    
    // コインの単位の変換
    var money = data.Maximum/0.01;
    
    // WebGLへパラメタ送信
    SendMessage("sample","bill",money);
  });

});


```

`SendMessage()`の第1引数に「object名」を第2引数に「関数名」、第3引数に「料金」でWebGLに渡すパラメータを指定して、WebGL側の関数「bill」を呼び出します。
これでボタンがクリックされると、利用料金に応じた数のコインが生成されて出てきます。


#実行・検証

動画でどうぞ


[https://www.youtube.com/watch?v=WyyBQhYuPiY](https://www.youtube.com/watch?v=WyyBQhYuPiY "")

[![](http://img.youtube.com/vi/WyyBQhYuPiY/0.jpg)](https://www.youtube.com/watch?v=WyyBQhYuPiY)

現実世界のコインに置き換えた方がわかりやすいと思いました。
同じ手法で、銀行預金を3Dで表現したい。自分の部屋に預金全てを1円玉でバラまいたらどうなるか等、いくらでも表現の仕方が思いつきます。

更に大きい視点だと、ビッグデータとUnityの連携だとか。
非ゲーム分野でのUnityの活用が叫ばれていますが、データ分析・データシミュレーションの分野でもUnityは活用できると思います。