【Unity(C#)】API通信勉強メモ①

##やばい
本当に何もわかりません。
今までネットワークとかサーバサイドとか全て無視し続けてきたツケが回ってきました。


##必要な技術を言語化する

やりたいことはわかってました。

**・Webサイトで登録したアカウントとUnityで作ったexeファイルを紐づけたい**
**・アカウント登録してないとexeを使えないようにしたい**

しかし、これを**実現するのに必要な技術がわかりません**でした。

検索ワードで　「Unity　サーバー　通信」などで調べると運よく
[初心者が送る UnityでAPI通信講座](https://qiita.com/pchan52/items/feca16ea98289ec31c65)　がヒットしました。

自分のやりたいことっぽかったので、
ひとまず、できないといけないことが**「UnityでAPI通信」**だと判明しました。

##インターネット上の画像を描写する
[参考リンク](https://qiita.com/pchan52/items/feca16ea98289ec31c65#%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%8D%E3%83%83%E3%83%88%E4%B8%8A%E3%81%AE%E7%94%BB%E5%83%8F%E3%82%92%E6%8F%8F%E5%86%99%E3%81%99%E3%82%8B)

####つまづいたところ

[スクリプトに記述](https://qiita.com/pchan52/items/feca16ea98289ec31c65#%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%81%AB%E8%A8%98%E8%BF%B0)　のコードにある、画像のURLがよくわかりませんでした。

####画像のURLって何？
[Google Drive に保存した画像を直接呼び出せるURLの取得](https://qiita.com/arribux/items/0394968fa318d9309d33)
↑ こちらの方法で解決しました。

`WWW`を利用する方法と[**UnityWebRequest**を利用する方法](https://toylabo.tech/blog/skills/770/)どちらも動かしてみてちゃんと動きました。

```C#
using System.Collections;
using UnityEngine.Networking;
using UnityEngine;

public class GetImage : MonoBehaviour
{
    string url = "画像のURL";

    void Start()
    {
        //それぞれコメントアウトして片方ずつ試した。どっちもちゃんと動いた。
        StartCoroutine(GetImageFromURL());
        StartCoroutine(GetImageWebRequest());
    }

    IEnumerator GetImageFromURL()
    {
        //Unityでは通信が行われたフレームでは値が返ってこないのでコルーチンを使用。
        //WWWクラスはWebにアクセスするためのクラスで、サーバーにGETとPOSTを行うことが可能。
        WWW www = new WWW(url);

        //wwwの値が返ってくるまで処理を止める。
        yield return www;

        //www.textureは、WWWクラスに定義されていて、ダウンロードしたデータからTexture2Dを返す。
        GetComponent<Renderer>().material.mainTexture = www.texture;
    }

    IEnumerator GetImageWebRequest()
    {
        UnityWebRequest request = UnityWebRequestTexture.GetTexture(url);

        //リクエストが通るまで(?)処理を止める。
        yield return request.SendWebRequest();

        Texture2D texture2D = new Texture2D(600, 600);

        //texture2D.LoadImageでbyte配列から画像をロード。
        texture2D.LoadImage(request.downloadHandler.data);
        GetComponent<Renderer>().material.mainTexture = texture2D;
    }
}
```


![Request.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/efca82c1-d667-3b13-c8a9-b595bb152160.gif)


##GETとPOST

そもそもGETとPOSTがよくわからないのでここを参考にしました。
[HTTPとPOSTとGET](https://qiita.com/Sekky0905/items/dff3d0da059d6f5bfabf)


コードに落とし込む方法はここを見ました。
[UnityでHTTPに接続する](https://qiita.com/ponchan/items/65aeb43e8fea8da0bcac)

####つまづいたところ
接続するURLってなに？ってなりました。

なんでもよかった？のかもしれませんが、こちらを参考に開発用ローカルサーバーというのを立ち上げました。
[開発用ローカルサーバを立ち上げる方法](https://qiita.com/higuma/items/b23ca9d96dac49999ab9)

```:Python3入れてコマンドプロンプトで実行
python -m http.server 8000
```

しかし、POSTはうまくいかず、
どうやらサーバー側でPOSTメソッドを受け取った際の処理を書かないといけない(?)ようです。
![PostError.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/b76559af-3587-6c3b-8295-de34b54086e0.png)


##Json

JsonでAPIと値のやり取りをすることになる(?)ようなので
やり方を調べました。

サーバー側はまだよくわからないので、
`http://IPアドレス:8000`をブラウザで開くと表示されるディレクトリ(`C:\Users\ユーザー名`)の直下に
Jsonファイルを作って配置して実験しました。

```C#
using System.Collections;
using LitJson;
using UnityEngine;
using UnityEngine.Networking;

public class JsonTest : MonoBehaviour {

    public UserData userData = new UserData();
    public string url = "http://IPアドレス:8000";
    public string jsonName;

    IEnumerator Start()
    {
        userData.name = "Yamada";
        userData.age = 20;
        string jsondata = JsonMapper.ToJson(userData);
        print(jsondata);
        WWWForm form = new WWWForm();
        form.AddField("jsondata", jsondata);

        //これはおそらくPOSTになってしまう
        //var www = new WWW(url, form);
        //yield return www;
        //print(www.text);

        UnityWebRequest webRequest = UnityWebRequest.Get(url+ "/"+jsonName);
        //URLに接続して結果が戻ってくるまで待機
        yield return webRequest.SendWebRequest();

        Debug.Log("Get" + " : " + webRequest.downloadHandler.text);
    }
}

```

`var www = new WWW(url, form);`はPOSTになってしまうので(?)、つながりませんでした。


用意したJsonファイルはこちらです。
適当にテキストファイル作って拡張子を`json`にするだけです。
書き方のルールはここにありました。 
[JSON入門](http://www.tohoho-web.com/ex/json.html)

```:onoJson.json
{"name": "HIKAKIN", "age": 100}
```

ちゃんと動いてました。


![JsonTest.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/b5c071f0-638c-5566-75dd-9d143a29bb8b.png)


そういえば、何気に今日はじめて
`IEnumerator Start`という使い方を見ました。

↓こんな便利な使い方もあって目から鱗でした
[【Unity】Startのコルーチン完了後にUpdate処理を開始したい](http://tsubakit1.hateblo.jp/entry/2015/11/16/000000)

次やることとしては、サーバー側の処理をよしなにして、POSTを試したいです。

---

やりました→[【Unity(C#),Python】API通信勉強メモ②Flaskでローカルサーバー立ち上げ](https://qiita.com/OKsaiyowa/items/0f8c0fe030abf0b490ed)