[英]Unity3D Coroutine Error
我被Unity腳本困住了。 我有3個文件: Scene.cs , Player.cs和NetworkUtil.cs 。 我無法編譯我的代碼,因為我不知道如何將Coroutine響應傳遞回Scene。
在Scene.cs
( MonoBehavior
類)中:
void OnGUI() {
if(GUI.Button(new Rect(0, 0, 100, 100), "Register")) {
StartCoroutine(registerPlayer());
}
}
IEnumerator registerPlayer() {
return Player.NewPlayer("Raptor"); // since Player is not IEnumerator, this line causes error.
}
在Player.cs
( Object
class)中:
public static Player NewPlayer(string name) {
Player p = new Player();
result = p.tryRegister();
if(result) {
return p;
} else {
return null;
}
}
private bool tryRegister() {
Dictionary<string, string> data = new Dictionary<string, string>();
data.Add("some_key", "some_value");
NetworkUtil.ExecuteAPI(data);
}
在NetworkUtil.cs
( Object
class)中:
public static IEnumerator ExecuteAPI(Dictionary<string, string> data) {
WWWForm form = new WWWForm();
form.AddField("mode", request);
foreach(KeyValuePair<string, string> entry in data) {
form.AddField(entry.Key, entry.Value);
}
WWW handler = new WWW(API_URL, form);
yield return handler;
if(handler.error != null) {
Debug.Log("Error occurred: " + handler.error); // Server Error
} else {
Debug.Log("Response: " + handler.text);
}
}
如何更改代碼以使流程完整?
注意:在Object
類中, StartCoroutine()
不存在。
編輯
我已更改代碼以使用“代表和事件”:
// DelegatesAndEvents.cs
public class DelegatesAndEvents : MonoBehaviour {
public delegate void RegisterEventHandler(Player player);
public static event RegisterEventHandler onPlayerRegister;
public static void NewPlayerRegistered(Player player) {
if(onPlayerRegister != null) {
onPlayerRegister(player);
}
}
}
然后在Scene.cs
:
void Start() {
DelegatesAndEvents.onPlayerRegister += this.userRegistered;
}
public void userRegistered(Player player) {
Debug.Log("User registered.");
}
我應該如何將觸發器放入NetworkUtil.cs
& Player.cs
?
這樣做有多種方法,因為您不僅需要返回IEnumerator
,而且要在其上進行迭代的是Unity本身,因此您不可能捕獲返回值。
從技術上講,可以執行以下操作:
IEnumerator registerPlayer() {
yield return Player.NewPlayer("Raptor"); // this is legal, player will be the Current value of the IEnumerator
}
如果您想做類似上面的代碼的事情,則需要將 coroutine
包裝在另一個內,然后自己對其進行迭代(我做了類似的實現行為樹的操作):
IEnumerator Wrap(IEnumerator playerRegister)
{
while(playerRegister.MoveNext())
{
Player p = playerRegister.Current as Player; //this can be done if you know what you are doing
yield return null;
}
}
另一種方法是不返回任何內容,而是將委托傳遞給coroutine
,這將被稱為將必需的參數傳遞回調用方。
就像是:
IEnumerator DoSomething(Action<Response> whenDone)
{
while (doingSomething)
yield return null;
whenDone(response);
}
編輯
您的代碼的另一個問題是您正在從Player
的構造函數內部調用另一個協程( ExecuteAPI
)。 因此,使registerPlayer成為協程是沒有意義的,因為您不會產生任何結果。
在您的情況下,最簡單的方法是將一個委托傳遞給ExecuteAPI
,當您從服務器收到響應時將調用該委托。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.