web-dev-qa-db-ja.com

Unity GET / POSTラッパー

これはUnity3d in C#の質問です。目標は、URLを渡してGETを介してデータを受信できるようにオブジェクトを作成することです。作成するオブジェクトは、WWWロジックのラッパーになります。また、投稿の引数として、キーと値のペアのURLと「辞書」を指定できる「POST」オブジェクトも必要です。結構...私たちは最終的にこのようなものを望みます:

get_data = GET.request("http://www.someurl.com/somefile.php?somevariable=somevalue");

そして

post_data = POST.request("http://www.someurl.com/somefile.php", post)
// Where post is a Dictionary of key-value pairs of my post arguments. 

これを実行するために、私はWWWオブジェクトを使用します。ここで、WWWオブジェクトにダウンロードする時間を与えるために、これをMonoBehaviourオブジェクト内で実行し、yield結果を取得する必要があります。だから私はこれを手に入れました、それはうまくいきます:

public class main : MonoBehavior
{
    IEnumerator Start()
    {
        WWW www = new WWW("http://www.someurl.com/blah.php?action=awesome_stuff"); 
        yield return www;
        Debug.Log(www.text);
    }
}

私が本当に欲しいのはこれです:

public class main : MonoBehavior
{
    IEnumerator Start()
    {
        GET request = new GET("http://www.someurl.com/blah.php?action=awesome_stuff"); 
        Debug.Log(request.get_data()); // Where get_data() returns the data (which will be text) from the request.   
    }
}

これで、メインスクリプトが階層内の単一のGameObject(ルートと呼ばれる)にアタッチされました。ルートGETにもGameObjectスクリプトをアタッチする必要がありますか? mainから動的に実行できますか?

最終的には、GETおよびPOSTリクエストを簡単に送信できるソリューションが必要です。

乾杯!

17

ああ、わかった!

私の問題は、MonoBehaviourとコルーチンがどのように機能するかについての誤解でした。解決策は非常に簡単です。

エディターで、空のゲームオブジェクトを作成します。 DBと名付けました。次に、次のスクリプトを添付します。

using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
class DB : MonoBehaviour
{
    void Start() { }

    public WWW GET(string url)
    {
        WWW www = new WWW(url);
        StartCoroutine(WaitForRequest(www));
        return www;
    }

    public WWW POST(string url, Dictionary<string, string> post)
    {
        WWWForm form = new WWWForm();
        foreach (KeyValuePair<String, String> post_arg in post)
        {
            form.AddField(post_arg.Key, post_arg.Value);
        }
        WWW www = new WWW(url, form);

        StartCoroutine(WaitForRequest(www));
        return www;
    }

    private IEnumerator WaitForRequest(WWW www)
    {
        yield return www;

        // check for errors
        if (www.error == null)
        {
            Debug.Log("WWW Ok!: " + www.text);
        }
        else
        {
            Debug.Log("WWW Error: " + www.error);
        }
    }
}

次に、メインスクリプトの開始関数でこれを行うことができます!

private DB db;
void Start()
{
    db = GameObject.Find("DB").GetComponentInChildren<DB>();
    results = db.GET("http://www.somesite.com/someAPI.php?someaction=AWESOME");
    Debug.Log(results.text);
}

POSTリクエストをテストしていませんが、すべてのロジックが完了しました!HTTPリクエストをあなたの心の欲望に送ってください、乾杯!

17

あなたが参照しているGETスクリプトは何ですか? WWWクラスを使用すると、GETデータを適切に取得できます。必要な情報は、インスタンス化されたWWWオブジェクトのtextプロパティにあります。ここにドキュメントがあります:

http://unity3d.com/support/documentation/ScriptReference/WWW-text.html http://unity3d.com/support/documentation/ScriptReference/WWW.html

必要なのは、今行っているようにWWWオブジェクトを生成し、次に、必要なプロパティをプレーンでシンプルに読み取るだけです。追加のクラスは必要ありません。

POSTオブジェクトの送信に関しては、それがWWWFormクラスの目的です。

http://unity3d.com/support/documentation/ScriptReference/WWWForm.html

つまり、WWWFormオブジェクトを作成し、AddField()を使用してフィールドを追加し、POST URLと以前のオブジェクトを使用して新しいWWWオブジェクトを作成するだけです。それだけです。 WWWオブジェクトと、それが返ってきたら、データが送信されています。応答は、対応するフィールドのテキストプロパティとエラーにあります。プレーンで、クリーンでシンプルです。

HTH!

2
jmpp

@pandemoniumsyndicateのコードを変更して、コールバックを追加します。 GETおよびPOST関数はコルーチンを呼び出した直後に終了するため、元のコードは完全に正しくありません。その時点では、WWWリクエストがまだ完了しておらず、(www.isDone)は無意味です。

次のコードは、デリゲートWWWRequestFinishedを定義しています。デリゲートは、リクエストの結果と受信したデータがある場合は、リクエストが終了したときに呼び出されます。

using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class WWWRequestor : MonoBehaviour 
{

    Dictionary<WWW, object> mRequestData = new Dictionary<WWW, object>();
    public delegate void WWWRequestFinished(string pSuccess, string pData);

    void Start() { }

    public WWW GET(string url, WWWRequestFinished pDelegate)
    {
        WWW aWww = new WWW(url);
        mRequestData[aWww] = pDelegate;

        StartCoroutine(WaitForRequest(aWww));
        return aWww;
    }

    public WWW POST(string url, Dictionary<string, string> post, WWWRequestFinished pDelegate)
    {
        WWWForm aForm = new WWWForm();
        foreach (KeyValuePair<String, String> post_arg in post)
        {
            aForm.AddField(post_arg.Key, post_arg.Value);
        }
        WWW aWww = new WWW(url, aForm);

        mRequestData[aWww] = pDelegate;
        StartCoroutine(WaitForRequest(aWww));
        return aWww;
    }

    private IEnumerator WaitForRequest(WWW pWww)
    {
        yield return pWww;

        // check for errors
        string aSuccess = "success";
        if (pWww.error != null)
        {
            aSuccess = pWww.error;
        }

        WWWRequestFinished aDelegate = (WWWRequestFinished) mRequestData[pWww];
        aDelegate(aSuccess, pWww.text);
        mRequestData.Remove(pWww);
    }

}
0
questionman