【問題】我希望可以在遊戲有連網的功能,而使用的協定是http協定。
根據官網的參考文章,有以下的範例參考:
using UnityEngine; using System.Collections; public class ExampleClass : MonoBehaviour { public string url = "http://images.earthcam.com/ec_metros/ourcams/fridays.jpg"; IEnumerator Start() { WWW www = new WWW(url); yield return www; renderer.material.mainTexture = www.texture; } }
官網的範例 連結
但是,當我在實作時,卻好像沒有這麼順利。
【我要作甚麼】我希望按下按鈕後,可以呼叫某個.php檔,再由該檔案傳回資訊。於是我在我的localhost設了一個.php檔案,呼叫該檔案只會回傳一個固定的字串"YAYAYAYA"。該字串我會顯示在Unity的console畫面。
首先,開啟一個新專案,對Camera設定一個C# script。
新增一個onGUI(),我想要一個按鈕在左上方。
void OnGUI(){ // A button if (GUI.Button (new Rect ( 0, 0, 100, 100), "Link")) { print("You click the button"); } }
我的localhost下有個檔案名為connect.php,內容如下:
/** * connect.php */ <?php echo "YAYAYAYA"; ?>
回到Unity,我又新增了一個function叫Send(),功能為送出需求與顯示回傳資訊,程式碼如下:
private IEnumerator Send(){ print("Do Link"); WWW rtn = new WWW(mUrl); yield return rtn;
print("Finish Link"); if((!string.IsNullOrEmpty(rtn.error))){ print ("Error return: "+rtn.error); } else{ Debug.Log(rtn.text); } }
我在第2行與第6行埋下了Log,運行這段程式時一定會顯示這兩行Log。
新增一個成員變數mUrl,為我們要連結的網址:
/*類別的成員變數*/ public string mUrl = "http://localhost/unity_serv/connect.php";
再稍微修改一下onGUI,使得按下按鈕時可以呼叫Send()。
void OnGUI(){ // A button if (GUI.Button (new Rect ( 0, 0, 100, 100), "Link")) { print("You click the button"); Send(); } }
執行畫面如下:
點了Link按鈕之後,下面Consloe只有顯示"You click the button"。而Send()中的Log完全沒有印,表示根本就沒有進來Send()。
【問題來了】
我幾番追查,發現是Send()中有行"yield return rtn;"這行有問題。如果沒有這一行(改成"return null"),則執行時就會進去Send()裡面。可是就沒有收到任何的資訊,表示我們呼叫網頁是失敗的。
我努力在網路上搜尋yield的使用方式與介紹,可是用法幾乎都跟Unity官網上說的差不多。灰心之餘,突然找到一個函式 StartCoroutine() 。
修改一下onGUI()函式,把Send()包在StartCoroutine()的參數內:
void OnGUI(){ // A button if (GUI.Button (new Rect ( 0, 0, 100, 100), "Link")) { print("You click the button"); StartCoroutine(Send()); } }
再執行一次,結果如下圖:
這次總算有進去Send()而且也有成功的呼叫網頁了。
【想一想】為什麼要設定StartCoroutine()呢?
首先,yield return xx; 是需要與IEnumerator類型的函式使用,如果類型是void或是int等都會錯誤。
這整組的用法,目的在於為了要可以執行中斷。也就是說,當我們使用Send()這個函式時,他不會馬上去執行該函式,而是另外開一個執行緒去處理他。
然而,在Unity,WWW的用法在JavaScript與C#有些許的不同。官網上提到:
When using JavaScript it is not necessary to use StartCoroutine, the compiler will do this for you. When writing C# code you must call StartCoroutine.
所以,C#必須透過使用StartCoroutine()去開啟一組IEnumerator函式與yield的使用。
熱血啊!成功解決問題!繼續邁向偉大航道前進!
留言列表