2017-10-11 79 views
3

enter image description here 在上面的短片中,您會看到我在Unity中的設置相當簡單。有一個計數器每幀增加一個(在Update中),一邊是這個調用'UnityEditor.SceneView.RepaintAll()'。你可以看到一個輸出到控制檯的計數器。如何在運行時刷新Unity?

一旦我進入遊戲視圖並點擊左下角的一個按鈕(突出顯示的按鈕按下),它會調用一個腳本,該腳本在運行時將網格導入場景並呈現它。在此期間,您會注意到計數器和重繪通話凍結,儘管時間很短,但非常明顯。實際上,在加載時間內,場景中的所有內容都會凍結。

我一直在谷歌搜索如何刷新Unity的場景,以便我本質上可以在運行時加載網格,同時保持對播放器的響應。到目前爲止,沒有。

這裏定期刷新/更新場景的最佳做法是什麼,以便玩家不會受到加載時間遊戲暫停的影響?

編輯:RepaintAll()調用不適用於我。以前應該添加。我曾希望它會,其實我不完全相信它的目的是什麼,如果不刷新場景此方法不起作用

網格導入代碼:

const int MAX_FACETS_PER_MESH = 65535/3; 

    class Facet 
    { 
     public Vector3 normal; 
     public Vector3 a, b, c; 

     public override string ToString() 
     { 
      return string.Format("{0:F2}: {1:F2}, {2:F2}, {3:F2}", normal, a, b, c); 
     } 
    } 

    private static Mesh[] ImportBinary(string path) 
    { 
     Facet[] facets; 

     using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read)) 
     { 
      using (BinaryReader br = new BinaryReader(fs, new ASCIIEncoding())) 
      { 
       // read header 
       byte[] header = br.ReadBytes(80); 
       uint facetCount = br.ReadUInt32(); 
       facets = new Facet[facetCount]; 

       for(uint i = 0; i < facetCount; i++) 
       { 
        facets[i] = new Facet(); 

        facets[i].normal.x = br.ReadSingle(); 
        facets[i].normal.y = br.ReadSingle(); 
        facets[i].normal.z = br.ReadSingle(); 

        facets[i].a.x = br.ReadSingle(); 
        facets[i].a.y = br.ReadSingle(); 
        facets[i].a.z = br.ReadSingle(); 

        facets[i].b.x = br.ReadSingle(); 
        facets[i].b.y = br.ReadSingle(); 
        facets[i].b.z = br.ReadSingle(); 

        facets[i].c.x = br.ReadSingle(); 
        facets[i].c.y = br.ReadSingle(); 
        facets[i].c.z = br.ReadSingle(); 

        // padding 
        br.ReadUInt16(); 
       } 
      } 
     } 

     return CreateMeshWithFacets(facets); 
    } 

    private static Mesh[] CreateMeshWithFacets(IList<Facet> facets) 
    { 
     int fl = facets.Count, f = 0, mvc = MAX_FACETS_PER_MESH * 3; 
     Mesh[] meshes = new Mesh[fl/MAX_FACETS_PER_MESH + 1]; 

     for(int i = 0; i < meshes.Length; i++) 
     { 
      int len = System.Math.Min(mvc, (fl - f) * 3); 
      Vector3[] v = new Vector3[len]; 
      Vector3[] n = new Vector3[len]; 
      int[] t = new int[len]; 

      for(int it = 0; it < len; it += 3) 
      { 
       v[it ] = facets[f].a; 
       v[it+1] = facets[f].b; 
       v[it+2] = facets[f].c; 

       n[it ] = facets[f].normal; 
       n[it+1] = facets[f].normal; 
       n[it+2] = facets[f].normal; 

       t[it ] = it; 
       t[it+1] = it+1; 
       t[it+2] = it+2; 

       f++; 
      } 

      meshes[i] = new Mesh(); 
      meshes[i].vertices = v; 
      meshes[i].normals = n; 
      meshes[i].triangles = t; 
     } 

     return meshes; 
    } 
+0

請參閱[this](https://stackoverflow.com/a/46488319/3785314)post如何使用ThreadPool和UnityThread類執行此操作 – Programmer

+0

@Programmer「[One]可以啓動單獨的線程...只要他們沒有調用在該線程中執行的任何Unity函數「,引用鏈接中的'lockstock'。我想象使用Mesh構造函數的導入代碼(參見上文)意味着它不能在新線程中運行。 – jtth

+0

@lockstock這種情況? – jtth

回答

4

你要嘗試執行同步文件IO,它可以鎖定正在運行的任何線程。在這種情況下,主線程。

你可以看到這個鎖的效果在剪輯的所有三個領域:

  • 場景視圖不會更新
  • 遊戲視圖不更新
  • 控制檯停止記錄

這是因爲Update()根本沒有運行。

爲了解決這個問題,你需要異步加載文件。

+0

很好解釋,謝謝Draco。那麼這裏的修復就像使這些功能異步一樣簡單? – jtth

+0

@jtth你將不得不做一些研究。我沒有異步執行任何System.FileIO事情,只有統一的東西(例如Resources)。我做了一個粗略的搜索,但它只是反映了我已經知道的事情。 – Draco18s

+0

使用(非常簡單但出類拔萃的)TPL任務,我認爲在Unity的.Net 3.5運行時中不可用,您將不得不使用單獨的線程來執行如此繁重的計算。但是請記住,線程在WSA應用程序中不可用。 – Arshia001

相關問題