Доступ к сопрограмме через неназначенный (неизвестный) компонент - PullRequest
0 голосов
/ 21 октября 2018

Добрый день, возможно мой вопрос покажется вам глупым!но я до сих пор не могу найти ответ!Как будто, чтобы уменьшить код, все мои попытки провалились в пропасть, я просто не знаю, что делать = (

У меня много строк:

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

1 Ответ

0 голосов
/ 21 октября 2018

Вы не можете сделать это без медленного отражения, в зависимости от того, как часто это делается.

Чтобы упростить ваш код, вы должны использовать Dictionary или предоставить способчтобы перевести _ID в вашу функцию.Поскольку вы выполняете каждый вызов функции сопрограммы, вы должны хранить каждую функцию как IEnumerator, чтобы вы могли ее получить.

Словарь:

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

Функция для добавления идентификаторов и их функций в словарь.Вызовите эту функцию из функции 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));
}

Чтобы использовать ее, проверьте значение _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);
}

РЕДАКТИРОВАТЬ:

Другой вариант - заменить _ID на string.Эта строка должна содержать имя сценария.Затем вы можете использовать отражение и ключевое слово 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.Смотрите этот пост.Это должно работать, но используйте словарную версию этого кода, потому что это быстрее.

...