Unity GET / POST包装器

时间:2012-01-21 07:45:08

标签: c# post get web unity3d

这是C#问题中的Unity3d。目标是创建一个对象,以便我可以传入一个URL并通过GET接收数据,我将创建一个对象作为WWW逻辑的包装器。我也想要一个'POST'对象,在那里我可以提供一个url和一个键值对的'Dictionary'作为帖子争论。 Sooo ......我们最终会喜欢这样的事情:

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(称为root)。我是否还需要将GET脚本附加到根GameObject?我可以从main动态执行此操作吗?

最终,我需要一个允许我轻松发送GETPOST请求的解决方案。

干杯!

3 个答案:

答案 0 :(得分:17)

啊,明白了!

我的问题是对MonoBehaviour和Coroutines如何运作的误解。解决方案非常简单。

在编辑器中,制作一个空的GameObject。我把它命名为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请求给你的心愿,欢呼!

答案 1 :(得分:2)

您所指的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&amp; amp; new构建一个新的WWW对象。前一个对象就是这样。产生WWW对象,一旦它返回,您的数据已经提交。回复再次出现在文本属性&amp;相应字段中的错误。平原,干净&amp;简单。

HTH!

答案 2 :(得分:0)

这是修改@ pandemoniumsyndicate的代码以添加回调。原始代码不完全正确,因为GETPOST函数将在调用协程后立即退出。那时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);
    }

}