Unity GET/POST 包装器

Posted

技术标签:

【中文标题】Unity GET/POST 包装器【英文标题】:Unity GET/POST Wrapper 【发布时间】:2012-02-15 14:43:22 【问题描述】:

这是 C# 中的 Unity3d 问题。目标是创建一个对象,以便我可以传入 URL 并通过 GET 接收数据,我将创建的对象将是 WWW 逻辑的包装器。我也想要一个“POST”对象,我可以在其中提供一个 url 和一个键值对的“字典”作为帖子参数。太好了……我们最终想要这样的东西:

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 动态执行此操作吗?

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

干杯!

【问题讨论】:

【参考方案1】:

啊,明白了!

我的问题是对 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 请求到你心中的愿望,干杯!

【讨论】:

虽然使用 FIND 方法的大问题是你的游戏性能会受到很大影响....试图找到一个游戏对象....查看如何工作的好链接与代表unifycommunity.com/wiki/… 绝对正确。理想情况下,您将通过引用变量跟踪对象,并挂在它上面,因此您只需要这样做一次。或者如果场景中的游戏对象正在使用这个包装器,你可以有一个公共变量,可以在 Unity 编辑器中分配 DB GO,那么你不需要找到任何东西! 我认为这实际上行不通。执行时: StartCoroutine(WaitForRequest(request)) Debug.Log(request.text) 如果请求尚未完成,则只会停止协程,而不是实际功能。在请求完成之前将调用哪个 Debug.Log(request.text)。 提比留是对的。您需要使用回调函数。 @ThePoet 它定义在 POST 函数的正下方,几乎没有消息说明请求是否完成。【参考方案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 和以前的对象构造一个新的 WWW 对象,就是这样。产生 WWW 对象,一旦它返回,您的数据就已提交。同样,响应位于相应字段的文本属性和错误中。简单、干净、简单。

HTH!

【讨论】:

对不起,GET对象是封装了WWW逻辑的类。我需要做的就是提供一个 URL 并接收一个输出。但是,鉴于统一的工作方式,我不确定这是否可能。我将编辑我的问题。【参考方案3】:

这是@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);
    


【讨论】:

以上是关于Unity GET/POST 包装器的主要内容,如果未能解决你的问题,请参考以下文章

Unity 包装器中的 Cubemos 骨架跟踪 SDK,未找到 realsense2.dll,未找到 cubemos_engine.dll,未初始化 RealSense 管道!错误

如何正确地将浮点指针从 C 库传递到其 C# 包装器

Unity资源管理系统 ——YooAsset学习笔记事件管理器EventManager

C++11——— 包装器

C++11——— 包装器

属性包装器到属性包装器