Инициирование сопрограммы в общедоступной статической пустоте в Unity?

#c# #unity3d #c#-4.0 #coroutine #ienumerator

#c# #unity3d #c #-4.0 #сопрограмма #ienumerator

Вопрос:

Да, я буквально застрял на простой Сопрограмме. В моей игре Unity я пытался выяснить, как использовать что-то подобное в общедоступной статической пустоте:

 StartCoroutine(ExampleCoroutine())
 

Я понимаю, что нет никакого способа использовать эту строку в общедоступной статической пустоте, но я пытаюсь найти обходной путь, который бы делал то же самое. До сих пор Интернет не помогал, но ближе всего к решению моей проблемы я подошел к созданию экземпляра. Я не понял этого, потому что я всего лишь новичок, но это может быть зацепкой, так как это ошибка, которую я получаю при создании:

 error CS0120: An object reference is required for the non-static field, method, or property 'MonoBehaviour.StartCoroutine(IEnumerator)'
 

IEnumerator, который запускается сопрограммой, помечен как public static, если это вообще помогает.
Спасибо, что уделили мне время и потакаете моей глупости

РЕДАКТИРОВАТЬ: меня попросили показать больше кода, так что я иду!

 public static void NeedsToBeAccessedElsewhere()
{
     StartCoroutine(NeedsDeley());
     //Do Stuff
}

public static IEnumerator NeedsDelay()
{
     //results
}
 

Комментарии:

1. Нет. Я пытаюсь запустить сопрограмму в общедоступной статической пустоте.

2. Да, это то, что я задаюсь вопросом, что делать.

3. Я поделился ошибкой, в которой говорилось то же самое.

4. С правкой покончено.

Ответ №1:

Сопрограмме всегда нужен экземпляр MonoBehaviour , который отвечает за ее возбуждение. Следовательно StartCoroutine , это не a static , а метод экземпляра и должен вызываться для экземпляра MonoBehavior .

Таким образом, если ваш метод static , вам либо нужно передать MonoBehaviour ссылку, например,

 public static void NeedsToBeAccessedElsewhere(MonoBehaviour instance)
{
     instance.StartCoroutine(NeedsDeley());
}

public static IEnumerator NeedsDelay()
{
     //results
}
 

Или в качестве запасного варианта вы могли бы убедиться, что существует поведение по умолчанию, которое создается по требованию

 public class CoroutineExecuter : MonoBehaviour { }
 

и делать

 private static CoroutineExecuter instance;

public static void NeedsToBeAccessedElsewhere()
{
    if(!instance)
    {
        instance = FindObjectOfType<CoroutineExecuter>();

        if(!instance)
        {
            instance = new GameObject ("CoroutineExecuter").AddComponent<CoroutineExecuter>();
        }
    }

    instance.StartCoroutine(NeedsDeley());
}

public static IEnumerator NeedsDelay()
{
     //results
}
 

Обратите внимание, однако, в целом: вы прокомментировали // Do stuff , но имейте в виду этот вызов. StartCoroutine завершается немедленно и не задерживает вызывающий его метод. Если это был ваш план, вам лучше передать обратный вызов, например

 public static IEnumerator NeedsDelay(Action afterDelay)
{
     yield return new WaitForSeconds(3f);

     afterDelay?.Invoke();
}
 

и используйте его, например,

 instance.StartCoroutine(NeedsDelay(() =>
{
    Debug.Log("Delay has finished");
}));
 

Комментарии:

1. Извините, что вернулся поздно: я получил эту ошибку: Ошибка CS7036: не указан аргумент, соответствующий требуемому формальному параметру ‘instance’ ‘MyScript. MyVoid (MonoBehaviour) ‘

2. @Spectre ну, тогда вы не передали требуемый экземпляр 😉