Как дождаться завершения функции в сценарии 1, прежде чем запускать сценарий 2? - PullRequest
0 голосов
/ 18 октября 2018

В Unity у меня есть GameObjectName, к которому прикреплен скрипт 1 и скрипт 2.Script1 - это IEnumerator, подобный этому.

public IEnumerator Sunglasses()
{
    // Do stuff
}

Script2 выглядит следующим образом.

public void Start()
{
    Function1();
    String blah = "Things";
    Function2();
    StartCoroutine(Routine2());
    StartCoroutine(Routine3());
}

Мне нужен сценарий 1, чтобы закончить Sunglasses, прежде чем сценарий 2 что-нибудь сделает.Если я попытаюсь получить доступ к GameObjectName.Script1 из Script2, Unity скажет, что его не существует.Как я могу убедиться, что сценарий 1 завершается до запуска сценария 2?

Ответы [ 2 ]

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

Вы можете добавить логическую переменную в первый скрипт, после завершения вызова функции Sunglasses установите для нее значение true.

Script1:

public bool isDone = false;

public IEnumerator Sunglasses()
{
    // Do stuff

    isDone = true;
}

Script2:

Затем в вашем Script2 вы можете сделать свою функцию Start функцией сопрограммы или IEnumerator вместо функции void.После этого вы можете подождать, пока isDone будет истинным в каждом кадре.

public bool isDone;
Script1 script1Ref;

public IEnumerator Start()
{
    GameObject s1Obj = GameObject.Find("GameObjectScript1IsAttachedTo");
    script1Ref = s1Obj.GetComponent<Script1>();

    //Wait here until we are done
    while (!script1Ref.isDone)
        yield return null;

    //Done Waiting, now continue with the rest of the code
    Function1();
    String blah = "Things";
    Function2();
    StartCoroutine(Routine2());
    StartCoroutine(Routine3());
}

Наконец, если вам также необходимо убедиться, что Script1 работает перед тем, как что-то делать в функции Update Script2,просто проверьте переменную isDone и верните, если она все еще false.

void Update()
{
    //Return if script 1 is not done
    if (!script1Ref.isDone)
        return;

    //The rest of your code below


}

Обратите внимание, что вы хотите, чтобы StartCoroutine(Routine3()) ждал, пока StartCoroutine(Routine2()) не будет сделано, вы должны вернуть его,

Заменить StartCoroutine(Routine3()) на yield return StartCoroutine(Routine3()).

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

Вы можете попробовать изучить события или шаблон наблюдателя.Я использовал последнее, что позволяет мне добавлять обратные вызовы со строковым идентификатором.Для событий вы делаете что-то вроде

public static event System.Action onSunglassesCompleted;
public IEnumerator Sunglasses()
{
    //Sunglasses logic here

    //if there is a listener to the event, call it
    if(onSunglassesCompleted != null)
    {
        onSunglassesCompleted();
    }
}

Затем в Script2 вам просто нужно добавить слушателя к событию

void Start()
{
    Script1.onSunglassesCompleted += DoThisAfterSunglasses;
}

//This will be called in Script1
void DoThisAfterSunglasses()
{
    //Make sure you do this to avoid memory leaks or missing reference errors once Sprite1 is destroyed
    Script1.onSunglassesCompleted -= DoThisAfterSunglasses;

    Function1();
    String blah = "Things";
    Function2();
    StartCoroutine(Routine2());
    StartCoroutine(Routine3());
}

Одна вещь, которую вы можете сделать в событиях, чтобы избежать утечек, этоустановив его в null после его вызова.

if(onSunglassesCompleted != null)
{
    onSunglassesCompleted();
    onSunglassesCompleted = null;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...