#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 ну, тогда вы не передали требуемый экземпляр 😉