2016年5月14日土曜日

【Unity】WebAPIに接続してデータを取得する

PHPでもAndroidでも、過去の開発経験からいって、WebAPIに接続してデータを取得するという課題は必ずつきまとうし、また初回はつまづきが大きい。
でも一度やり方が分かってしまうと、あとは作っておいたライブラリファイルに処理を丸投げして終わりとか、コードのコピペ で終わりとか、さらりと出来てしまう。

なので、UnityでWebAPIに接続するサンプルを作っていた。

それなりに出来たのでGitHubにあげました。
https://github.com/ishiitakeru/Unity_WebApiConnectSample

主要なスクリプトはこれ
https://github.com/ishiitakeru/Unity_WebApiConnectSample/blob/master/WebApiConnectSample/Assets/script/ConnectWebApiSample.cs

説明。
WebAPIに接続して値をプロパティに格納する機能を持つのがWWWクラスのインスタンス。
POSTデータを送信するために使うのがWWWFormクラスのインスタンス。
WWWクラスをnewするときに WWWFormのインスタンスを引数に渡してやることでPOSTデータを送信する。

留意ポイントは、 WWWクラスのインスタンスは通信によって状態が変わるということ。
つまり、newした直後はWebAPIからのレスポンスがまだ受け取れていないので、取得した値を取り出せない。
しばらくして通信が完了すると、WWWインスタンスのプロパティから通信で手に入れたデータを取り出せる。
ということは、WWWインスタンスを生成したあと、その状態を時間経過に従って監視し続ける仕組みが必要。

そこで、コルーチンを使う。
コルーチンになっているメソッドでは、毎フレーム、yield return から次の yield returnまでが実行される。

つまり、コルーチンメソッドのすごいところは、 ひとつのメソッド内で時間経過で状態が変わることを取り込んで実現できるということだ。

そこで、WWWインスタンスによってWebAPIに接続するコルーチンメソッドは以下のような作りになるはず。

----------------------------------------------------------------------
private IEnumerator コルーチンメソッド名(){

    //WebAPIにPOSTデータを送信するための WWWForm インスタンス
    WWWForm my_www_form = new WWWForm();
    //キーと値とのセットを登録
    my_www_form.AddField("key", "value");

    //WWWクラスのインスタンス作成
    WWW my_www = new WWW(
        "http://WebAPIのURL", //WebAPIのURL
        my_www_form  //POST送信値をセットしたWWWFormインスタンス
    );

    //↑ここまでは一度だけ実行されれば良い
    //↓ここからは通信によるデータ取得が完了するまで繰り返し実行される必要がある
    while(true){
        //1フレームで、yield return から次の yield return まで実行される。
        yield return null;

        //WWW.isDone プロパティによって通信が完了したかどうかを調べられる。
        if(my_www.isDone == true){
            //通信完了
            //WWWインスタンスからデータ取り出し
            Debug.Log("Apiレスポンス : " + my_www.text);
            break;

        }else{
            //まだ通信が完了してない
        }//if
    }//while
 }//function
----------------------------------------------------------------------

コツ :
■WWWインスタンスは一度作ればいいので毎フレーム繰り返されるループの外で作っておく。
■WWW.isDone プロパティの確認を毎フレーム繰り返されるループ内で行う。

Androidの場合、別スレッドで通信処理を開始して、データ取得が終わったらそれを検知するコールバックメソッドからデータを取り出して、みたいにかなり複雑なことをやった記憶がある。

[Androidの場合]
■通信用にメインの処理とは別の非同期処理スレッドを作成し、通信はそこでしなくてはならない。
■通信完了を検知するコールバックメソッドを使い、通信で手に入れたデータをそこで取り出さないといけない。

UnityはAndroidに作りが似ているのかなと思ったけど、どうも、WebAPIとの通信においては非同期スレッドもコールバックメソッドも使わない(あるいは意識しないで良い)ということみたい。

その代わり、毎フレーム「yield return 」から「yield return 」まで繰り返し実行されるコルーチンという仕組みをきちんと理解する必要があるようですな。

0 件のコメント:

コメントを投稿