通过未分配(未知)组件访问协程
Access to the Coroutine through an unassigned(unknown) component
下午好,也许您会觉得我的问题很愚蠢!但我还是找不到答案!好像要减少代码,我所有的尝试都沉入了深渊,我只是不知道该怎么办=(
我有很多字符串:
int _ID = Attacker.GetComponent<BaseHeroStats>().ID_Model;
if (_ID == 1) { yield return StartCoroutine(Elements[5].GetComponent<ID1>().StartAttack(EnemysInBattle, HeroesInBattle, Attacker)); }
else if(_ID == 2) { yield return StartCoroutine(Elements[5].GetComponent<ID2>().StartAttack(EnemysInBattle, HeroesInBattle, Attacker)); }
else if(_ID == 3) { yield return StartCoroutine(Elements[5].GetComponent<ID3>().StartAttack(EnemysInBattle, HeroesInBattle, Attacker)); }
else if(_ID == 4) { yield return StartCoroutine(Elements[5].GetComponent<ID4>().StartAttack(EnemysInBattle, HeroesInBattle, Attacker)); }
else if(_ID == 5) { yield return StartCoroutine(Elements[5].GetComponent<ID5>().StartAttack(EnemysInBattle, HeroesInBattle, Attacker)); }
....
如何获得这样的东西,或者至少工作:
int _ID = Attacker.GetComponent<BaseHeroStats>().ID_Model;
yield return StartCoroutine(Elements[5].GetComponent("ID" + _ID).StartAttack(EnemysInBattle, HeroesInBattle, Attacker));
没有反射就无法做到这一点,反射速度很慢,具体取决于这样做的频率。
为了简化您的代码,您必须使用 Dictionary
或提供一种将 _ID
转换为您的函数的方法。由于您要生成每个协程函数调用,因此您必须将每个函数存储为 IEnumerator
以便您可以生成它。
词典:
Dictionary<int, IEnumerator> idToDict = new Dictionary<int, IEnumerator>();
将 ID 添加到词典的功能及其功能。从 Awake
或 Start
函数调用此函数。
void InitIDs()
{
idToDict.Add(1, Elements[5].GetComponent<ID1>().StartAttack(EnemysInBattle, HeroesInBattle, Attacker));
idToDict.Add(2, Elements[5].GetComponent<ID2>().StartAttack(EnemysInBattle, HeroesInBattle, Attacker));
idToDict.Add(3, Elements[5].GetComponent<ID3>().StartAttack(EnemysInBattle, HeroesInBattle, Attacker));
idToDict.Add(4, Elements[5].GetComponent<ID4>().StartAttack(EnemysInBattle, HeroesInBattle, Attacker));
idToDict.Add(5, Elements[5].GetComponent<ID5>().StartAttack(EnemysInBattle, HeroesInBattle, Attacker));
}
要使用它,请检查 Dictionary
中的 _ID
值。如果它存在,则执行与之配对的协程函数,然后像您在原始代码中所做的那样产生每一个:
int _ID = Attacker.GetComponent<BaseHeroStats>().ID_Model;
IEnumerator action;
//Check if the function name exist, start it then yield it
if (idToDict.TryGetValue(_ID, out action))
{
//Execute the approprite code
yield return StartCoroutine(action);
}
编辑:
另一种选择是用 string
替换您的 _ID
。该字符串应该包含脚本的名称。然后,您可以使用反射和 dynamic
关键字来调用 coroutine
函数。因此,int _ID
现在应该是包含脚本名称的 string _ID
。这也意味着 BaseHeroStats
class 中的 ID_Model
变量现在应该是 string
.
例如这样的事情:
string _ID = "ID2";
Type type = Type.GetType(_ID);
Component ids = GetComponent(type);
dynamic val = Convert.ChangeType(ids, type);
StartCoroutine(val.StartAttack());
或者在您自己的代码示例中:
string _ID = Attacker.GetComponent<BaseHeroStats>().ID_Model;
Type type = Type.GetType(_ID);
Component ids = Elements[5].GetComponent(type);
dynamic val = Convert.ChangeType(ids, type);
yield return StartCoroutine(val.StartAttack(EnemysInBattle, HeroesInBattle, Attacker));
您必须启用 .NET 4.6 才能使用 dynamic
关键字。参见 post。这应该可行,但使用此代码的字典版本,因为它更快。
下午好,也许您会觉得我的问题很愚蠢!但我还是找不到答案!好像要减少代码,我所有的尝试都沉入了深渊,我只是不知道该怎么办=(
我有很多字符串:
int _ID = Attacker.GetComponent<BaseHeroStats>().ID_Model;
if (_ID == 1) { yield return StartCoroutine(Elements[5].GetComponent<ID1>().StartAttack(EnemysInBattle, HeroesInBattle, Attacker)); }
else if(_ID == 2) { yield return StartCoroutine(Elements[5].GetComponent<ID2>().StartAttack(EnemysInBattle, HeroesInBattle, Attacker)); }
else if(_ID == 3) { yield return StartCoroutine(Elements[5].GetComponent<ID3>().StartAttack(EnemysInBattle, HeroesInBattle, Attacker)); }
else if(_ID == 4) { yield return StartCoroutine(Elements[5].GetComponent<ID4>().StartAttack(EnemysInBattle, HeroesInBattle, Attacker)); }
else if(_ID == 5) { yield return StartCoroutine(Elements[5].GetComponent<ID5>().StartAttack(EnemysInBattle, HeroesInBattle, Attacker)); }
....
如何获得这样的东西,或者至少工作:
int _ID = Attacker.GetComponent<BaseHeroStats>().ID_Model;
yield return StartCoroutine(Elements[5].GetComponent("ID" + _ID).StartAttack(EnemysInBattle, HeroesInBattle, Attacker));
没有反射就无法做到这一点,反射速度很慢,具体取决于这样做的频率。
为了简化您的代码,您必须使用 Dictionary
或提供一种将 _ID
转换为您的函数的方法。由于您要生成每个协程函数调用,因此您必须将每个函数存储为 IEnumerator
以便您可以生成它。
词典:
Dictionary<int, IEnumerator> idToDict = new Dictionary<int, IEnumerator>();
将 ID 添加到词典的功能及其功能。从 Awake
或 Start
函数调用此函数。
void InitIDs()
{
idToDict.Add(1, Elements[5].GetComponent<ID1>().StartAttack(EnemysInBattle, HeroesInBattle, Attacker));
idToDict.Add(2, Elements[5].GetComponent<ID2>().StartAttack(EnemysInBattle, HeroesInBattle, Attacker));
idToDict.Add(3, Elements[5].GetComponent<ID3>().StartAttack(EnemysInBattle, HeroesInBattle, Attacker));
idToDict.Add(4, Elements[5].GetComponent<ID4>().StartAttack(EnemysInBattle, HeroesInBattle, Attacker));
idToDict.Add(5, Elements[5].GetComponent<ID5>().StartAttack(EnemysInBattle, HeroesInBattle, Attacker));
}
要使用它,请检查 Dictionary
中的 _ID
值。如果它存在,则执行与之配对的协程函数,然后像您在原始代码中所做的那样产生每一个:
int _ID = Attacker.GetComponent<BaseHeroStats>().ID_Model;
IEnumerator action;
//Check if the function name exist, start it then yield it
if (idToDict.TryGetValue(_ID, out action))
{
//Execute the approprite code
yield return StartCoroutine(action);
}
编辑:
另一种选择是用 string
替换您的 _ID
。该字符串应该包含脚本的名称。然后,您可以使用反射和 dynamic
关键字来调用 coroutine
函数。因此,int _ID
现在应该是包含脚本名称的 string _ID
。这也意味着 BaseHeroStats
class 中的 ID_Model
变量现在应该是 string
.
例如这样的事情:
string _ID = "ID2";
Type type = Type.GetType(_ID);
Component ids = GetComponent(type);
dynamic val = Convert.ChangeType(ids, type);
StartCoroutine(val.StartAttack());
或者在您自己的代码示例中:
string _ID = Attacker.GetComponent<BaseHeroStats>().ID_Model;
Type type = Type.GetType(_ID);
Component ids = Elements[5].GetComponent(type);
dynamic val = Convert.ChangeType(ids, type);
yield return StartCoroutine(val.StartAttack(EnemysInBattle, HeroesInBattle, Attacker));
您必须启用 .NET 4.6 才能使用 dynamic
关键字。参见