2015-05-28 11 views
6

Jednym ze skryptów na mojej scenie jest tworzenie siatki sześcianów. Proces ten zajmuje sporo czasu i próbuję go wdrożyć, nie powodując, że Unity przestaje reagować.Ładowanie siatki za pomocą coroutines - odczekaj do końca,

Obecny kod - działa na zasadzie efektu - można oglądać podczas generowania siatki. Jednak inne skrypty na scenie wykonują swoje zadania w tym samym czasie i powodują wyjątki (uzyskują dostęp do płytek w siatce, które nie zostały jeszcze utworzone).

Poniższy skrypt jest jedynym skryptem, który ma funkcję "Przebudźcie się" - inne skrypty wykonują polecenia "Aktualizuj" i "OnGUI", zanim pierwszy skrypt się zakończy.

GridGenerator.cs 

public GameObject[,] tiles = new GameObject[Constants.BOARD_WIDTH, Constants.BOARD_HEIGHT]; 
    // Run a double loop to create each tile. 
    void Awake() 
    { 
     StartCoroutine(doSetup()); 
    } 

    IEnumerator doSetup() 
    { 
     yield return StartCoroutine (loadLevel()); 
     DoOtherStuff(); 
    } 

    IEnumerator loadLevel() 
    { 
     for (int i = 0; i < Constants.BOARD_WIDTH; i++)    
     { 
      for (int j = 0; j < Constants.BOARD_HEIGHT; j++) 
      { 
       tiles[i,j] = newTile(); 
       yield return(0); 
      } 
     } 
    } 

Jak sprawić, by metoda doOtherStuff() czekała aż zakończy się procedura współprzewodnicząca?

Próbowałem logiczną przerzutowe (który zamarzł jedności) próbowałam za pomocą zamka (który nie działa)

lub tam jest bardziej efektywny sposób to zrobić?

EDYCJA: Kod pomyślnie uzupełnia OtherStuff() po wygenerowaniu siatki. Poza doOtherStuff() jest przekazywanie odniesienia do siatki do oddzielnej klasy. Oddzielna klasa rzuca wyjątki podczas próby uzyskania dostępu do siatki w metodzie aktualizacji. Co sugeruje, metoda aktualizacji jest wywoływana przed ukończeniem Przebudźcie się w GridGenerator.cs.

+0

więc inne rzeczy szukasz płytek, czy jest jakiś sposób, że gdy oni Ponownie szukając ich mogą stwierdzić, czy zostały wygenerowane i są jeszcze dostępne? może potrzebować dostarczyć więcej kodu, który pokazuje, jak płytki są przechowywane/dostępne przez inne procedury. – DLeh

+0

Tak, to jest rozwiązanie - sprawdzanie, czy płytki są generowane jako pierwsze. Ale będzie to wymagało dodania dodatkowych warunków do wszystkich miejsc, które wymagają płytek ... Ah, płytki są przechowywane w wielowymiarowej tablicy GameObjects. Zaktualizowano główny post - dzięki. – user1662292

Odpowiedz

1

Najprostszym sposobem byłoby skopać swój współprogram w innym współprogram, tak aby można było poddać się nim:

void Awake() 
{ 
    StartCoroutine(doSetup()); 
} 

IEnumerator doSetup() 
{ 
    yield return StartCoroutine(createGrid()); // will yield until createGrid is finished 
    doOtherStuff(); 
} 

IEnumerator createGrid() 
{ 
     for (int i = 0; i < Constants.BOARD_WIDTH; i++)    
     { 
      for (int j = 0; j < Constants.BOARD_HEIGHT; j++) 
      { 
       // Instantiate a new tile 
       yield return(0); 
      } 
     } 
    } 
} 
+0

Witam, dziękuję za odpowiedź i działa to w pewnym stopniu. Ignorowanie logu, działa poprawnie i generowana jest siatka. Jednak nadal wychodzi z funkcji Przebudź się przed generowaniem siatki, w wyniku czego inne skrypty rejestrują wyjątki. Jest znacznie lepsza niż w rzeczywistości (jak wcześniej rozbił się w połowie generowania siatki). Wszelkich pomysłów na to, jak go zatrzymać po wyjściu z trybu czuwania aż do ukończenia siatki? – user1662292

+3

Metoda "Przebudźcie się" nie może być coroutine, a więc nie może ulec innej korporacji. Będziesz musiał albo refactor do obsługi asynchronicznego tworzenia siatki, albo po prostu zrobić to synchronicznie. – Problematic