初心者が送る UnityでAPI通信講座

# 目的
unityで通信を行い、データベースへ情報を保存したり、データベースから情報を取得したりする。

# 学習内容
・URLから直接データを持ってくる
・データベースへ情報を保存する
・データベースから情報を取り出す

# インターネット上の画像を描写する

## 新規Unityアプリケーションを作成する
新規アプリケーションを作成して開発を行うための準備を行います。

Unityを起動して、ページ上部にあるNEWを選択して下さい。

[![https://gyazo.com/f409583b987805393d5fd5018baac470](https://i.gyazo.com/f409583b987805393d5fd5018baac470.png)](https://gyazo.com/f409583b987805393d5fd5018baac470)

Project nameの入力欄に、「wwwtest」と入力して下さい。作成者が指定のフォルダ以下になっていることを確認します。3Dを選択した後に、Create projectを選択し、Projectを作成して下さい。

[![https://gyazo.com/cd26862e9dd6a5725876dd2104a7be80](https://i.gyazo.com/cd26862e9dd6a5725876dd2104a7be80.png)](https://gyazo.com/cd26862e9dd6a5725876dd2104a7be80)

以下のようになっていれば大丈夫です。

[![https://gyazo.com/f0c8b8568a58f11ca46787d46a93c11a](https://i.gyazo.com/f0c8b8568a58f11ca46787d46a93c11a.png)](https://gyazo.com/f0c8b8568a58f11ca46787d46a93c11a)

## オブジェクトを配置する
シーン上にPlaneを配置して下さい。位置はInspectorビューの**Possition**で指定できます。

**Plane**

Transform|x|y|z|
:--|:----|:----|:----
Position|0|0|0|
Rotation|0|0|0|
Scale|1|1|1|

以下のようになっていれば大丈夫です。

[![https://gyazo.com/1153d33a3a24c6fecc7f5c338334a472](https://i.gyazo.com/1153d33a3a24c6fecc7f5c338334a472.png)](https://gyazo.com/1153d33a3a24c6fecc7f5c338334a472)

## Main Cameraの位置を変更する
GameビューにPlaneが上手く配置されるようにMainCameraの位置と回転を設定していきます。これらは、Inspectoreビューで設定できます。

**Main Camera**

Transform|x|y|z|
:--|:----|:----|:----
Position|0|5|8|
Rotation|30|180|0|
Scale|1|1|1|

[![https://gyazo.com/3827354ecb9b6abc8695d3839b90c261](https://i.gyazo.com/3827354ecb9b6abc8695d3839b90c261.png)](https://gyazo.com/3827354ecb9b6abc8695d3839b90c261)

Gameビューが以下のようになっていれば大丈夫です。

[![https://gyazo.com/d68054d45fe14461d3a38b67367a470f](https://i.gyazo.com/d68054d45fe14461d3a38b67367a470f.png)](https://gyazo.com/d68054d45fe14461d3a38b67367a470f)


## Scriptsフォルダを作成する
Projectビュー内のAssets以下にScriptsフォルダを作成しましょう。

ProjectビューのAssetの上で右クリックをし、Createの中からFolderを選択して下さい。

[![https://gyazo.com/e68200c547cc455fd553850e69872486](https://i.gyazo.com/e68200c547cc455fd553850e69872486.png)](https://gyazo.com/e68200c547cc455fd553850e69872486)

すると、以下のようにNew Folderが作成されます。

[![https://gyazo.com/ea150c28055edb968598a86b2a905d25](https://i.gyazo.com/ea150c28055edb968598a86b2a905d25.png)](https://gyazo.com/ea150c28055edb968598a86b2a905d25)

New Folderを選択している状態で「New Folder」と書かれている部分をクリックすると名前を変更出来るようになります。名前を「Scripts」にして下さい。
以下の動画も参考にして下さい。

[![https://gyazo.com/c087f7d685238ef50baf36b5cb686eef](https://i.gyazo.com/c087f7d685238ef50baf36b5cb686eef.gif)](https://gyazo.com/c087f7d685238ef50baf36b5cb686eef)

## Scenesフォルダを作成する
Scriptsフォルダを作成したときと同様に、Scenesフォルダも作成しましょう。

以下のようになっていれば大丈夫です。

[![https://gyazo.com/7d2e412ac0a7454b0e57cf08d2a4f6e1](https://i.gyazo.com/7d2e412ac0a7454b0e57cf08d2a4f6e1.png)](https://gyazo.com/7d2e412ac0a7454b0e57cf08d2a4f6e1)

## Sceneを保存する
⌘キーの後に、⌘キーを押したまま「ｓ」を押して、Sceneを保存しましょう。Sceneの名前は「test」としましょう。

[![https://gyazo.com/bcdf0d2beeddc208cc810e9e0cb56b27](https://i.gyazo.com/bcdf0d2beeddc208cc810e9e0cb56b27.png)](https://gyazo.com/bcdf0d2beeddc208cc810e9e0cb56b27)

＊ Unityは突然ソフトがおちることがあるので、Sceneの保存はこまめに行うようにしましょう。

## スクリプトを作成
インターネット上の画像をPlaneに描写するスクリプトを記述します。
ScriptsフォルダのなかにConnectionTest.csスクリプトを作成しましょう。
以下のようになっていれば大丈夫です。

[![https://gyazo.com/8f1a902a6c87266819560f7035ad4738](https://i.gyazo.com/8f1a902a6c87266819560f7035ad4738.png)](https://gyazo.com/8f1a902a6c87266819560f7035ad4738)


## スクリプトに記述
実際にスクリプトを記述し、Planeに画像を描写しましょう。
ProjectビューのScriptsフォルダにある**「ConnectionTest.cs」**を以下のように編集して下さい。

```csharp:Connection.cs
using System.Collections;
using UnityEngine;

public class ConnectionTest : MonoBehaviour {

	string url = "http://cdn-www.dailypuppy.com/media/dogs/anonymous/coffee_poodle01.jpg_w450.jpg";

	// Use this for initialization
	void Start () {
		StartCoroutine (Connect ());
	}
	
	// Update is called once per frame
	void Update () {
		
	}

	private IEnumerator Connect(){
		var www = new WWW (url);
		yeild return www;
		GetComponent<Renderer> ().material.mainTexture = www.texture;
	}
}
```

追加した部分を見ていきましょう。

**6行目**

```csharp
	string url = "http://cdn-www.dailypuppy.com/media/dogs/anonymous/coffee_poodle01.jpg_w450.jpg";
```

文字列型(string型)の変数urlを定義し、画像のURLを代入しています。

**10行目**

```csharp
StartCoroutine (Connect ());
```

コルーチンの開始を宣言します。
コルーチンとは実行を指定時間止める機能のことです。

**18行目**

```csharp
private IEnumerator Connect(){
}
```

コルーチン関数の宣言を行っています。
unityでは通信を行う場合、通信が行われたフレームで値が返ってこないため、コルーチンを用います。

**19行目**

```csharp
var www = new WWW(url);
```

### var
Variant型と呼ばれ、何でも格納できる便利な変数です。スクリプトのコンパイル時に正しい型へと評価されます。

```csharp
var a = 1;
var itemList = new List<int>();
```

と記述をすると、コンピュータが自動的にaはint型と、itemListはList<int>型であると認識してくれます。つまり以下の記述と同じということになります。

```csharp
int a = 1;
List<int> itemList = new List<int>();
```

以下の２つの場合に主にvarを使います。
・単なる初期化なのにきわめて長いコードになる場合
・長い文字数の同じ型を２回も書かなければいけないような場合

注意点としては、以下の２つがあります。
・varを使う場合は必ず初期化しなければいけない
・複数の変数を宣言することは出来ない

具体的には以下のようなスクリプトです。

```csharp
var a;   \\初期化されていないのでエラーとなる
var a,b; \\複数宣言しているのでエラーとなる
```

＊コンパイルとは、プログラミング言語で書かれたコンピュータプログラムを解析し、コンピュータが直接実行可能な形式のプログラムに変換することをいいます。

### WWWクラス
WWWクラスとはWebにアクセスするためのクラスで、サーバーにGETとPOSTを行うことが可能です。
Webサーバからゲームのランキングやハイスコアなどのデータを取得する場合や、Webから画像を取得してテクスチャを生成したりするときに使用します。


**20行目**

```csharp
yeild return www;
```

wwwの値が返ってくるまで処理を止めます。wwwの値が返ってくると、この次の行から処理が開始します。

**21行目**

```csharp
GetComponent<Renderer> ().material.mainTexture = www.texture;
```

### texture
WWWクラスに定義されていて、ダウンロードしたデータからTexture2Dを返す。

オブジェクトのテクスチャーの設定は、Rendererに設定されているMaterialインスタンスに用意されていて、テクスチャーイメージの設定はmainTextureというプロパティとして用意され、情報が保管されています。
よって、ここでは、ConnetctionTest.csがアタッチされているオブジェクトのテクスチャーイメージにwwwのデータをTexture2Dに変換したものを代入しています。
これにより、Planeにurlで指定した画像が張り付きます。

## スクリプトをアタッチして実行
今作ったConnectionTest.csをPlaneにアタッチしましょう。
以下のようになっていれば大丈夫です。

[![https://gyazo.com/9166bf39cc48e342cd550d63f55af044](https://i.gyazo.com/9166bf39cc48e342cd550d63f55af044.png)](https://gyazo.com/9166bf39cc48e342cd550d63f55af044)

再生ボタンを押して、実行しましょう。
以下のようになっていれば、成功です。

[![https://gyazo.com/c175ea71992dbd2349544875c8e92ac7](https://i.gyazo.com/c175ea71992dbd2349544875c8e92ac7.gif)](https://gyazo.com/c175ea71992dbd2349544875c8e92ac7)


## 光の反射をなくしましょう
現在のままだと、Planeに当たる光が反射してしまい、一部白くなってしまっています。
この光の反射をなくしましょう。

[![https://gyazo.com/61fdbb250106cfe9837d0145aef98df0](https://i.gyazo.com/61fdbb250106cfe9837d0145aef98df0.png)](https://gyazo.com/61fdbb250106cfe9837d0145aef98df0)

## Materialの作成
光の反射をなくすためのMaterialを作成していきます。
ProjectビューのCreateのなかのMaterialを選択し、名前をPlaneとしましょう。
以下のようになっていれば大丈夫です。

[![https://gyazo.com/c023aa956605ffc7e1c6d7cdd91033ba](https://i.gyazo.com/c023aa956605ffc7e1c6d7cdd91033ba.png)](https://gyazo.com/c023aa956605ffc7e1c6d7cdd91033ba)

Planeを選択し、InspectoreビューのShaderのプルダウンメニューからUnlit->textureと選択しましょう。
以下の動画も参考にしてください。

[![https://gyazo.com/f84a2e926d7022a8ad77e6d892280fab](https://i.gyazo.com/f84a2e926d7022a8ad77e6d892280fab.gif)](https://gyazo.com/f84a2e926d7022a8ad77e6d892280fab)

## Materialをアタッチして実行
Planeに今作ったMaterialをアタッチしましょう。
以下のようになっていれば大丈夫です。

[![https://gyazo.com/83a7101fb5dec436586e2dee58eeb2f2](https://i.gyazo.com/83a7101fb5dec436586e2dee58eeb2f2.png)](https://gyazo.com/83a7101fb5dec436586e2dee58eeb2f2)

再生ボタンを押して、実行してみましょう。
以下のようになっていれば成功です。

[![https://gyazo.com/f7e14c67f44479293bca43f177951f3f](https://i.gyazo.com/f7e14c67f44479293bca43f177951f3f.png)](https://gyazo.com/f7e14c67f44479293bca43f177951f3f)


# データーベースに情報を保存する
unityではデータベースとのやりとりはJSON形式で行います。
JSONとはRubyのハッシュオブジェクトのような形式です。あるキーに対して、あるバリューが紐付いています。ハッシュと同じく、バリューをハッシュのようにすることで入れ子構造を作ることも可能です。

## Utilsのダウンロード
以下のボタンからLitJSON.dillをダウンロードしましよう。
[ダウンロード](https://www.dropbox.com/sh/pptdadzxbyz31bu/AAAmKbeyloKRZGsiLGFvrfaRa/LitJson.dll?dl=0)

[![https://gyazo.com/53db20c625f1c35b4c25adc82edc3d4b](https://i.gyazo.com/53db20c625f1c35b4c25adc82edc3d4b.png)](https://gyazo.com/53db20c625f1c35b4c25adc82edc3d4b)

Finderのダウンロードの部分にLitJSON.dillというものが存在するのでそれをUnityのProjectビューにドラッグアンドドロップをしましょう。

[![https://gyazo.com/a0569c517f3d745ba9c855ef818e711f](https://i.gyazo.com/a0569c517f3d745ba9c855ef818e711f.png)](https://gyazo.com/a0569c517f3d745ba9c855ef818e711f)

分からない方は以下の動画も参考にして下さい。

[![https://gyazo.com/9c1895a2af5092416c75b73779184cfb](https://i.gyazo.com/9c1895a2af5092416c75b73779184cfb.gif)](https://gyazo.com/9c1895a2af5092416c75b73779184cfb)

## UserData.csの作成と編集
ProjectビューのScriptsフォルダを選択した状態でProjectビューのCreateを選択し、Folderを選択して下さい。新しく作成したフォルダをUserDataという名前にして下さい。

[![https://gyazo.com/089163d0046093bf8d4aa21364db2a73](https://i.gyazo.com/089163d0046093bf8d4aa21364db2a73.png)](https://gyazo.com/089163d0046093bf8d4aa21364db2a73)

Dataフォルダを選択し、Create->C# Scriptを選択し、UserData.csスクリプトを作成して下さい。

[![https://gyazo.com/a3930254b9abe1529e764840a0f817b0](https://i.gyazo.com/a3930254b9abe1529e764840a0f817b0.png)](https://gyazo.com/a3930254b9abe1529e764840a0f817b0)


UserData.csを以下のように編集して下さい。

```csharp:UserData.cs
[System.SerializableAttribute]
public class UserData{

	public string name;
	public int age;
}
```

このスクリプトではクラスの定義のみを行うので、名前空間やイベント関数を必要としません。
名前空間とはスクリプトを作成したときに1,2行目に書かれいてるusingの次に書かれているもので、クラスの入っているパッケージを記述したもので、イベント関数とはStart関数やUpdate関数のことです。

では、スクリプトを見ていきましょう。

**1行目**

```csharp
[System.SerializableAttribute]
```

###System.SerializableAttribute
クラスとクラス内に定義されたpublicな変数をInspectorビューに表示し、Inspectoreビューで編集することを可能にするものです。

**2~6行目**

```csharp
public class UserData{

	public string name;
	public int age;
}
```

UserDataクラスにstring型のnameとint型のageを定義しています。
これら２つの変数がInspectorビューで編集できるようになります。
後ほど、確認します。

## JsonTest.csの作成と編集
Scriptフォルダを選択し、ProjectビューのCreate -> C# ScriptからJsonTest.csを作成して下さい。

[![https://gyazo.com/ce700694bad42062829f05b590493bcb](https://i.gyazo.com/ce700694bad42062829f05b590493bcb.png)](https://gyazo.com/ce700694bad42062829f05b590493bcb)

次に、JsonTest.csを以下のように編集して下さい。

```csharp:JsonTest.cs
using System.Collections;
using UnityEngine;
using LitJson;

public class JsonTest : MonoBehaviour {

	public UserData userData = new UserData();
	public string url = "https://unity-api-falcon.herokuapp.com/api/users";

	// Use this for initialization
	IEnumerator Start () {
		userData.name = "Yamada";
		userData.age = 20;
		string jsondata = JsonMapper.ToJson (userData);
		print (jsondata);
		WWWForm form = new WWWForm ();
		form.AddField ("jsondata", jsondata);
		var www = new WWW (url, form);
		yield return www;
		print (www.text);
	}
	
	// Update is called once per frame
	void Update () {

	}
}
```

**3行目**

```csharp
using LitJson;
```

先程ダウンロードしたLitJsonを名前空間として使用しています。LitJsonはJSON読み書き用の名前空間で、データベースとの通信を行うために使います。

**7、8行目**

```csharp
public UserData userData = new UserData();
public string url = "https://unity-api-falcon.herokuapp.com/api/users";
```

UserData型の新たな変数userDataとstring型の変数urlを生成しています。
urlにはデータベースのURLを代入しています。

**11〜20行目**

```csharp
IEnumerator Start () {
    userData.name = "Yamada";
    userData.age = 20;
    string jsondata = JsonMapper.ToJson (userData);
    print (jsondata);
    WWWForm form = new WWWForm ();
    form.AddField ("jsondata", jsondata);
    var www = new WWW (url, form);
    yield return www;
    print (www.text);
}
```

通信ではコルーチンを必ず用いなければならず、Start関数はコルーチンにすることも出来るので、voidではなくIEnumeratorと型宣言します。
12、13行目では、UserDataクラスの変数userDataのnameとageに値を代入しています。

**14行目**

```csharp
string jsondata = JsonMapper.ToJson(userData);
```


### JsonMapper.ToJson
引数のデータをネットワークで送受信できるよう(Unityの場合はJSON形式)に変換します。
今回の場合は変換したものをstring型のjsondataという変数に格納しています。

**16、17行目**

```csharp
WWWForm form = new WWWForm ();
form.AddField ("jsondata", jsondata);
```

### WWWFormクラス
WWWクラスを使用してWebサーバーにデータをPOSTするフォームを生成するヘルパークラスです。

###AddField
WWWFormクラスのインスタンスに対して、使用します。第一引数にキー、第二引数にバリューを与えることで、送信する値を設定します。

今回においては、WWWFormクラスのインスタンス formを作成し、formにjsondataというキー、userDataをJSON形式にした値をバリューとするフィールドを作成していることになります。


## 空のGameObjectの作成
HierarchyビューのCreateからCreate Emptyを選択し、空のGameObject作成し、名前を「Jsontest」としましょう。

[![https://gyazo.com/59e13120429230fa9ccfae7691529141](https://i.gyazo.com/59e13120429230fa9ccfae7691529141.png)](https://gyazo.com/59e13120429230fa9ccfae7691529141)

## スクリプトをアタッチして実行
Hierarchy上のJsontestオブジェクトに、先程作成したJsontest.csをドラックアンドドロップをしてアタッチしましょう。

[![https://gyazo.com/1f893a528dd2dc1c091bbb72d060f0b1](https://i.gyazo.com/1f893a528dd2dc1c091bbb72d060f0b1.gif)](https://gyazo.com/1f893a528dd2dc1c091bbb72d060f0b1)

アタッチをすると、Inspectorビューにて先程定義したUserDateクラスを確認できます。

[![https://gyazo.com/e47793d9d174c7072c24c1bda621384d](https://i.gyazo.com/e47793d9d174c7072c24c1bda621384d.png)](https://gyazo.com/e47793d9d174c7072c24c1bda621384d)


最後にPlaneを非アクティブにしましょう。
HierarchyビューでPlaneを選択し、InspectorビューのPlaneの左のチェックボックスからチェックを外して下さい。

[![https://gyazo.com/1bd0dacb28f5e843afa997169c312b8d](https://i.gyazo.com/1bd0dacb28f5e843afa997169c312b8d.png)](https://gyazo.com/1bd0dacb28f5e843afa997169c312b8d)

それでは、再生ボタンを押して実行しましょう。
以下のようになっていれば成功です。

[![https://gyazo.com/6fd818b871965d14b2f1df9992dfe7d5](https://i.gyazo.com/6fd818b871965d14b2f1df9992dfe7d5.gif)](https://gyazo.com/6fd818b871965d14b2f1df9992dfe7d5)





# データベースから情報を取得する
## スクリプトの作成と編集
ProjectビューのScriptsフォルダの中のDataフォルダ内にReceiveUserData.csスクリプトを作成しましょう。

[![https://gyazo.com/1253b1e5498d563c1177e502047179e0](https://i.gyazo.com/1253b1e5498d563c1177e502047179e0.png)](https://gyazo.com/1253b1e5498d563c1177e502047179e0)

スクリプトの作成が出来たら、以下のように編集しましょう。

```csharp:ReceiveUserData.cs
[System.SerializableAttribute]
public class ReceieveUserInfoData {
	public int
		id,
		age;
	public string
		name,
		created_at,
		updated_at;
}
```

このスクリプトは先程のUserData.csと同様にクラスの定義のみを行っています。
int型のageとstring型のnameに加え、データベースに保存したデータの番号を表すint型のidとデータベースに保存した時刻、変更を加えた時刻を表すstring型のcreated_at、updated_atを宣言しています。
以下のように、Inspectorビューで確認ができます。

[![https://gyazo.com/5ea080b3e5e28dee19a688bb06337485](https://i.gyazo.com/5ea080b3e5e28dee19a688bb06337485.png)](https://gyazo.com/5ea080b3e5e28dee19a688bb06337485)

## JsonTest.csの編集
データベースから情報を受け取るための記述をJsonTest.csに加えます。 Scriptフォルダー内のJsonTest.csを以下のように編集して下さい。

```csharp:JsonTest.cs
using System.Collections;
using UnityEngine;
using LitJson;

public class JsonTest : MonoBehaviour {

	public UserData userData = new UserData();
	public ReceieveUserInfoData receiveUserInfoData = new ReceieveUserInfoData(); 
	public string url = "https://unity-api-falcon.herokuapp.com/api/users";

	// Use this for initialization
	IEnumerator Start () {
		userData.name = "hikaru";
		userData.age = 24;
		string jsondata = JsonMapper.ToJson (userData);
		print (jsondata);
		WWWForm form = new WWWForm ();
		form.AddField ("jsondata", jsondata);
		var www = new WWW (url, form);
		yield return www;
		print (www.text);
		receiveUserInfoData = JsonMapper.ToObject<ReceieveUserInfoData> (www.text);
	}
	
	// Update is called once per frame
	void Update () {
		print (receiveUserInfoData.name);
	}
}
```

追記した部分を順に見ていきましょう。

**8行目**

```csharp
public ReceieveUserInfoData receiveUserInfoData = new ReceieveUserInfoData(); 
```

先程作成した、ReceiveUserInfoDataクラスの変数receiveUserInfoDataを定義しています。

**22行目**

```csharp
 receiveUserInfoData = JsonMapper.ToObject<ReceieveUserInfoData> (www.text);
```

###JsonMapper.ToObject<>()
引数のJSON形式のデータを<>内で指定したクラスのオブジェクトに変換することで、Unity上で扱えるデータに変換します。
今回の場合はwww.testというデータベースから返ってきたJSON形式のデータに対して、ReceiveUserInfoData型を指定することで、receiveUserInfoDataがReceiveUserInfoData型のオブジェクトとなります。

**27行目**

```csharp
print (receiveUserInfoData.name);
```

receiveUserInfoDataのうちnameの情報を毎フレームコンソールに出力する記述です。nameの部分をidに変えると、idの情報がコンソールに出力されます。

## 実行しよう
再生ボタンを押して実行してみましょう。実行後、すこしするとInspectorビューのReceive User Info Dataの部分にデータが入り、コンソールにそのnameの部分が出力されていれば成功です。


[![https://gyazo.com/eb7b4cb5689299ee160cd9366e960d4b](https://i.gyazo.com/eb7b4cb5689299ee160cd9366e960d4b.gif)](https://gyazo.com/eb7b4cb5689299ee160cd9366e960d4b)


以上で、データベースとの通信ができるようになりました。これによって、ハイスコアやランキングの実装などが出来るようになります。