2012-01-21 3 views
17

이것은 Unity3d의 C#입니다. 목표는 URL을 전달하고 GET을 통해 데이터를받을 수 있도록 객체를 만드는 것입니다. 객체는 WWW 논리의 래퍼가 될 객체입니다. 나는 또한 'POST'객체를 원할 것이다. 여기서 URL과 post-arguements로 키 - 값 쌍의 'Dictionary'를 제공 할 수있다. SOOO ... 우리가 궁극적으로이 같은 싶습니다Unity GET/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에서 동적으로 처리 할 수 ​​있습니까?

궁극적으로 나는 GETPOST 요청을 쉽게 보낼 수있는 솔루션이 필요합니다.

건배!

답변

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

큰 문제는 FIND 방법을 사용하면 게임 성능에 큰 타격을 입게됩니다 .... 게임 개체를 찾으려고합니다 .... 대리인과 작업하는 방법에 대한 좋은 링크를 확인하십시오 http : // www .unifycommunity.com/wiki/index.php? title = CSharpMessenger_Extended –

+0

확실히 맞습니다. 이상적으로는 참조 변수를 통해 객체를 추적하고 그 객체에 매달 리므로 한 번만 수행하면됩니다. 장면의 게임 객체가이 래퍼를 사용하는 경우 Unity 편집기에서 DB GO를 할당 할 수있는 public var를 가질 수 있습니다. 그런 다음 아무 것도 찾을 필요가 없습니다! – PandemoniumSyndicate

+2

나는 이것이 실제로 작동한다고 생각하지 않는다. 수행중인 작업 : StartCoroutine (WaitForRequest (request)) Debug.Log (request.text) 요청이 아직 완료되지 않은 경우 실제 기능이 아닌 coroutine 만 중지됩니다. 어떤 Debug.Log (request.text)는 요청이 끝나기 전에 호출됩니다. –

2

당신이 말하는 GET 스크립트는 무엇입니까? WWW 클래스를 사용하면 GET 데이터를 정확하게 검색 할 수 있습니다. 필요한 정보는 인스턴스화 된 WWW 객체의 text 속성에 있습니다. 여기에 문서입니다 :

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

당신이 지금 막 일을하는지 된대로 WWW 객체를 생성하기 만하면, 관심이있는 속성을 평범하고 단순하게 읽고 추가 수업이 필요하지 않습니다.

한마디로 http://unity3d.com/support/documentation/ScriptReference/WWWForm.html

, 당신은 단지 다음, WWWForm 객체를 생성 AddField()를 통해 필드를 추가하고 : 게시물 개체를 전송으로

은, 그것은 WWWForm 클래스가 무엇인지입니다 POST URL이 & 인 이전 WWW 객체를 생성하십시오. WWW 개체를 얻으면 다시 데이터가 제출됩니다. 응답은 다시 해당 텍스트 필드의 텍스트 등록 정보 &에 있습니다. 평범하고 깨끗한 & 간단합니다.

HTH!

+0

죄송합니다. GET 객체는 WWW의 논리를 마무리하는 클래스입니다. 장점은 URL을 제공하고 출력을받는 것입니다. 그러나 단결이 어떻게 작동하는지에 대해서는 확신 할 수 없습니다. 내 질문을 수정하겠습니다. – PandemoniumSyndicate

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); 
    } 

}