首页 > 解决方案 > 通过未分配(未知)组件访问协程

问题描述

下午好,也许我的问题对你来说很愚蠢!但我还是找不到答案!好像为了减少代码,我所有的尝试都陷入了深渊,我只是不知道该怎么办=(

我有很多字符串:

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

标签: c#unity3dcoroutine

解决方案


你不能在没有反射的情况下做到这一点,这取决于这样做的频率。

为了简化您的代码,您必须使用Dictionary或提供一种方法将其转换_ID为您的函数。由于您要让出每个协程函数调用,因此您必须存储每个函数IEnumerator以便可以让出它。

词典:

Dictionary<int, IEnumerator> idToDict = new Dictionary<int, IEnumerator>();

将 ID 及其函数添加到 Dictionary 的函数。从Awakeor函数调用此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));
}

要使用它,请检查_ID. Dictionary如果存在,则执行与之配对的协程函数,然后像在原始代码中一样生成每个函数:

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

编辑:

另一种选择是将您的替换_IDstring. 该字符串应该包含脚本的名称。然后,您可以使用反射和dynamic关键字来调用该coroutine函数。所以,int _ID 现在应该是string _ID其中包含脚本的名称。这也意味着ID_Model您的类中的变量BaseHeroStats现在应该是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关键字。看到这个帖子。这应该可以,但使用此代码的字典版本,因为它更快。


推荐阅读