gpt4 book ai didi

c# - Unity 使用 IENumerator 设置另一个对象将使用的类

转载 作者:行者123 更新时间:2023-11-30 15:53:40 25 4
gpt4 key购买 nike

我正在尝试从我的数据库中创建另一个类使用的对象。但是由于 IEnumerator 的延迟响应(也许?),似乎存在问题。

我们有一个非常简单的敌人类来将 json 解析为:

[System.Serializable]
public class Enemy{
public string EnemyID;
public string Name;
}

BattleManager 附加到场景中的对象

public class BattleManager : Monobehaviour{

public Enemy debugEnemy;

void start()
{
//get a reference to the DBAccess
DBA = GameObject.Find("ManagerDB").GetComponent<DBAccess>();

debugEnemy = DBA.GetEnemy(1);
//debugEnemy EnemyID=0 and Name=""
//This is where the Problem is! Why is this not set from my DB?
}
}

现在这里是我从数据库中获取信息的地方。除了 GetEnemy 返回一个默认的 Enemy 对象而不是从 IEnumerator GetEnemyFromDB 中的 json 加载变量的对象之外,一切似乎都正常进行

public class DBAccess: Monobehaviour{

private Enemy enemy;

public Enemy GetEnemy(int EnemyID)
{
enemy = new Enemy();
StartCoroutine(GetEnemyFromDB(EnemyID));

//HERE enemy.EnemyID is 0 and enemy.Name is ""
return enemy;
}
private IEnumerator GetEnemyFromDB(int EnemyID)
{
WWWForm postData = new WWWForm();
postData.AddField("EnemyID", EnemyID);

WWW dbProc = new WWW(GetEnemyURL, postData);
yield return dbProc;

if (string.IsNullOrEmpty(dbProc.error)) //error is null or empty so: SUCCESS!
{
string jsonstring = "{\"Items\":" + dbProc.text + "}";

Enemy[] EnemiesFromDB;
EnemiesFromDB = JsonHelper.FromJson<Enemy>(jsonstring);

if (EnemiesFromDB.Length > 0)
{
enemy = EnemiesFromDB[0];
//HERE enemy.EnemyID is 1 and enemy.Name is "Evil Enemy Monster Man!"
//So it is working here!
}
else throw new System.Exception("No Enemy Found When Reading Json: " + JsonUtility.FromJson<Enemy>(jsonstring));

}
else throw new System.Exception("DB ERROR: " + dbProc.error);
}

}

我在 stackoverflow 上找到了这个辅助类。我忘了在哪里,否则我会给予适当的信任,但效果很好!

public static class JsonHelper
{
public static string RemoveBrackets(string s)
{
s = s.Replace("[", string.Empty);
s = s.Replace("]", string.Empty);
return s;
}

public static T[] FromJson<T>(string json)
{

Wrapper<T> wrapper = JsonUtility.FromJson<Wrapper<T>>(json);
return wrapper.Items;
}

public static string ToJson<T>(T[] array)
{
Wrapper<T> wrapper = new Wrapper<T>();
wrapper.Items = array;
return JsonUtility.ToJson(wrapper);
}

public static string ToJson<T>(T[] array, bool prettyPrint)
{
Wrapper<T> wrapper = new Wrapper<T>();
wrapper.Items = array;
return JsonUtility.ToJson(wrapper, prettyPrint);
}

[System.Serializable]
private class Wrapper<T>
{
public T[] Items;
}
}

super 令人沮丧,我想我已经阅读了 IEnumerator 上的一百万篇文章。我希望我可以让 IEnumerator 方法返回我的 Enemy 对象,而不是将私有(private)敌人作为受 IEnumerator 影响并由 getter 方法返回的变量。

非常感谢您的帮助!

最佳答案

非协程函数不能等待协程函数。如果您尝试强制执行此操作,则需要使用 Update 中的 bool 变量来执行此操作每一帧都起作用。我不建议那样做。使用 WWW 发出网络请求API 需要几帧左右。这意味着 GetEnemyFromDB在您尝试访问该值之前,函数调用尚未完成或返回。

在您的情况下,您必须进行以下更改:

1。你必须制作 GetEnemy执行协程函数,以便您可以等待 GetEnemyFromDB函数直到完成。这是通过 yield return 完成的声明。

2。要在协程函数的参数中设置对象,请使用 Action .在这种情况下,Action<Enemy> enemyResult是合适的。

3。更改 Start函数到协程函数。是的,你可以这么做。它是 Unity 为数不多的可以做成协程函数的回调函数之一。请注意,它是 Start不是start正如您输入问题中的代码一样。

你的新BattleManager类:

public class BattleManager : MonoBehaviour
{

public Enemy debugEnemy;

IEnumerator Start()
{
//get a reference to the DBAccess
DBAccess DBA = GameObject.Find("ManagerDB").GetComponent<DBAccess>();
yield return StartCoroutine(DBA.GetEnemy(1, (result) => { debugEnemy = result; }));

//YOU CAN NOW USE debugEnemy below

}
}

你的新DBAccess类:

public class DBAccess : MonoBehaviour
{
public IEnumerator GetEnemy(int EnemyID, Action<Enemy> enemyResult)
{
yield return StartCoroutine(GetEnemyFromDB(EnemyID, enemyResult));
}

private IEnumerator GetEnemyFromDB(int EnemyID, Action<Enemy> enemyResult)
{
WWWForm postData = new WWWForm();
postData.AddField("EnemyID", EnemyID);

WWW dbProc = new WWW(GetEnemyURL, postData);
yield return dbProc;

if (string.IsNullOrEmpty(dbProc.error)) //error is null or empty so: SUCCESS!
{
string jsonstring = "{\"Items\":" + dbProc.text + "}";

Enemy[] EnemiesFromDB;
EnemiesFromDB = JsonHelper.FromJson<Enemy>(jsonstring);

if (EnemiesFromDB.Length > 0)
{
//Pass result back to param
if (enemyResult != null)
enemyResult(EnemiesFromDB[0]);

//HERE enemy.EnemyID is 1 and enemy.Name is "Evil Enemy Monster Man!"
//So it is working here!
}
else throw new System.Exception("No Enemy Found When Reading Json: " + JsonUtility.FromJson<Enemy>(jsonstring));

}
else throw new System.Exception("DB ERROR: " + dbProc.error);
}
}

关于c# - Unity 使用 IENumerator 设置另一个对象将使用的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51942036/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com