2015-05-28 23 views
6

Một trong các kịch bản trong cảnh của tôi liên quan đến việc tạo ra một mạng lưới các hình khối. Quá trình này mất một lượng thời gian hợp lý và tôi đã cố gắng thực hiện nó mà không gây ra Unity trở nên không phản hồi.Đang tải lưới bằng coroutines - đợi cho đến khi kết thúc,

Mã hiện tại - hoạt động có hiệu lực - bạn có thể xem khi lưới được tạo. Tuy nhiên, các kịch bản khác trong cảnh đang thực hiện nhiệm vụ của họ cùng một lúc và đang gây ra ngoại lệ (họ đang truy cập các ô trên lưới chưa được tạo).

Kịch bản bên dưới là tập lệnh duy nhất có chức năng 'Đánh thức' - các tập lệnh khác đang thực thi 'Cập nhật' và 'OnGUI' trước khi tập lệnh đầu tiên kết thúc.

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

Tôi làm cách nào để phương thức doOtherStuff() đợi cho đến khi đồng thức kết thúc?

Tôi đã thử một chuyển đổi boolean (mà đóng băng đoàn kết) Tôi đã cố gắng sử dụng khóa (mà không làm việc)

Hoặc là có một cách hiệu quả hơn để làm điều này?

EDIT: Mã hoàn tất thành công OtherStuff() sau khi lưới được tạo. Ngoài doOtherStuff() là chuyển một tham chiếu của lưới tới một lớp riêng biệt. Lớp riêng biệt là ném ngoại lệ khi cố truy cập vào lưới trong phương thức Cập nhật. Điều này cho thấy, phương thức cập nhật đang được gọi trước khi Awake trong GridGenerator.cs được hoàn tất.

+0

nên những điều khác đang tìm kiếm gạch, là có một cách mà khi họ đang tìm kiếm họ, họ có thể cho biết họ có được tạo ra hay chưa? có thể cần phải cung cấp thêm mã hiển thị cách các ô được lưu trữ/truy cập bởi các thường trình khác – DLeh

+0

Có, đó là giải pháp - kiểm tra để đảm bảo các ô được tạo ra trước tiên. Nhưng sẽ liên quan đến việc thêm các điều kiện bổ sung cho tất cả các địa điểm yêu cầu gạch ... Ah, các ô được lưu trữ trong một mảng đa chiều của GameObjects. Đã cập nhật bài đăng chính - cảm ơn. – user1662292

Trả lời

1

Cách đơn giản nhất sẽ được khởi coroutine của bạn trong vòng coroutine khác, do đó bạn có thể mang lại cho nó:

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

Xin chào, Cảm ơn bạn đã phản hồi và điều này hoạt động ở một mức độ nào đó Bỏ qua nhật ký, hoạt động tốt và lưới được tạo. Tuy nhiên, nó vẫn thoát khỏi chức năng Awake trước khi lưới điện được tạo ra và kết quả là một số tập lệnh khác đang ghi nhật ký ngoại lệ Nó tốt hơn rất nhiều so với trước khi tạo lưới. Bất kỳ ý tưởng về làm thế nào để ngăn chặn nó thoát khỏi phương thức tỉnh táo cho đến khi lưới điện được hoàn thành? – user1662292

+3

Phương pháp 'Awake' không thể là một coroutine, và vì vậy không thể mang lại một coroutine khác. Bạn sẽ phải tái cấu trúc để xử lý việc tạo lưới không đồng bộ hoặc chỉ thực hiện đồng bộ. – Problematic

Các vấn đề liên quan