Unity可視化數據:建立圖表

本文由Aoi翻譯,轉載請註明出處。文章來自於catlikecoding,原文做者介紹了Unity製做圖表、可視化數據的方法。更多的名詞解釋內容,請點擊末尾的「原文連接」查看。html

 

 

介紹數組

這個教程裏,咱們在Unity 4裏用C#腳原本展現日趨複雜的圖表。你將學會:編輯器

  • 建立圖表,從簡單到複雜
  • 控制粒子系統
  • 寫各類數學函數
  • 在play模式下改變行爲
  • 使用Unity事件函數Start 和Update
  • 寫循環,包括單循環和嵌套循環
  • 使用數組、枚舉和表明

 

假設你已經對Unity編輯器有了初步的瞭解,而且知道建立C#腳本的基本知識。若是你完成了簡易時鐘製做教程,那麼你就能夠開始這一章了。函數

注意我會常常省略已經講解過的代碼塊。新的代碼內容會繼續講解清楚。
oop

準備佈局

打開一個新項目, 咱們將在一個單位的立方體內創建表格,放置於(0, 0, 0)和(1, 1, 1)之間。設置一下編輯器以獲得更好的視覺效果。4 Split是一個方便預約義的試圖佈局,因此選擇它。從Window / Layout / 4 Spit選擇,或者在屏幕右上方的下拉菜單裏。把全部的視圖模式都設置爲Textured,旋轉透視圖,這樣三個軸就都指向你了。this

經過GameObject / Create Other / Cube建立一個新的方塊,設置位置爲(0.5, 0.5, 0.5)。這爲咱們校準視圖提供參考。如今縮放和平移視圖使其聚焦於單位方塊。spa

最後,選擇Main Camera,經過GameObject / Align With View使其匹配立透視圖。若是那無論用,經過單機確認正確的視圖是否激活,而後再試試。翻譯

 

場景視圖以及相機聚焦於方塊3d

這個方塊再也不須要了,因此移除它。而後經過GameObject / Create Other / Particle System建立粒子系統並重置其變換。如今它能產生隨機例子了,可是不是咱們想要的,因此咱們停用除了渲染器以外的一切東西。

取消選擇Looping,  Play On AwakeEmission,以及Shape.這保留了惰性粒子系統,咱們能夠用它實現圖形數據可視化。

 

惰性粒子系統

建立第一個圖表

建立一個Y值依賴於X值的簡單圖線圖。咱們將用粒子的位置可視化這個。

重命名粒子系統對象爲Graph 1,建立C#腳本,命名爲Grapher1,做爲最小的GameObject類,而後將它做爲組件添加到對象。

1
2
3
using UnityEngine;
  
public class Grapher1 : MonoBehaviour {}
 

有着空 Grapher1組件的Graph 1

首先咱們的建立一些粒子做爲圖表的點。使用特殊的Start方法建立,這是一個在更新開始以前被調用一次的Unity事件方法。

咱們應該使用多少粒子呢?粒子越多,圖表的樣本分辨率就越高。咱們設置爲默認分辨率10。

1
2
3
4
5
6
7
8
using UnityEngine;
public class Grapher1 : MonoBehaviour {
    public int resolution = 10;
    private ParticleSystem.Particle[] points;
    void Start () {
        points = new ParticleSystem.Particle[resolution];
    }
}

 

Grapher1配置分辨率

如今咱們能夠按照本身的意願設置分辨率了。技術上至少是0,分辨率過高的話又會減慢運行。

咱們能夠確保初始化數組時變量在必定範圍內。若是分辨率超出了範圍,咱們就將其重設爲最小值,而且記錄警告信息。讓咱們用一個10-100的合理範圍。

1
2
3
4
5
6
7
void Start () {
        if (resolution < 10 || resolution > 100) {
            Debug.LogWarning("Grapher resolution out of bounds, resetting to minimum.", this);
            resolution = 10;
        }
        points = new ParticleSystem.Particle[resolution];
    }

如今該把點沿着X軸放置。第一個點應該放在0,最後一個放在1。其餘的點應該在這二者之間。因此距離,或者說X增量,兩點之間是1(分辨率-1)。

除了位置,咱們來能夠用顏色來提供相同的信息。讓點的紅色量等於其沿X軸的位置。

咱們將使用一個for循環來遍歷全部點,並設置位置和顏色,這是類型Vector3 和顏色的結構值。咱們還須要設置粒子的大小,不然將不會顯示。大小爲0.1就能夠。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void Start () {
        if (resolution < 10 || resolution > 100) {
            Debug.LogWarning("Grapher resolution out of bounds, resetting to minimum.", this);
            resolution = 10;
        }
        points = new ParticleSystem.Particle[resolution];
        float increment = 1f / (resolution - 1);
        for (int i = 0; i < resolution; i++) {
            float x = i * increment;
            points[i].position = new Vector3(x, 0f, 0f);
            points[i].color = new Color(x, 0f, 0f);
            points[i].size = 0.1f;
        }
    }

到目前爲止,還出不了效果。當播放的時候,什麼都顯示不出來。那是由於咱們得把粒子添加到粒子系統。方便起見,每一個組件都有一個粒子系統屬性,咱們能夠用它來訪問粒子系統(若是有的話)。咱們須要作的就是調用SetParticles方法,提供粒子數組以及咱們想要的粒子數量。因爲咱們想要使用全部的粒子,因此子要提供數組的長度就能夠。咱們須要給每一幀添加一個更新方法。

1
2
3
void Update () {
        particleSystem.SetParticles(points, points.Length);
    }
 
10粒子組成的線

就是這樣,如今咱們獲得了一個沿着X軸由黑到紅的點線。顯示多少點取決於分辨率的值。

 
分辨率爲十、100的線

如今,只有在圖表初始化的時候考慮分辨率。播放模式下更新值不起任何做用。如今來修改一下。

檢測分辨率的一個簡單方法是存儲兩次,而後常常檢查這兩個值是否仍然同樣。若是在某些點不同,咱們就要重建圖表。爲此須要建立一個私有變量currentResolution 。

因爲重建這些點適合初始化的時候是同樣的,因此把代碼移到名爲CreatePoints的新的私有方法中。這樣咱們就能從新使用代碼了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
using UnityEngine;
  
public class Grapher1 : MonoBehaviour {
  
    public int resolution = 10;
  
    private int currentResolution;
    private ParticleSystem.Particle[] points;
  
    void Start () {
        CreatePoints();
    }
  
    private void CreatePoints () {
        if (resolution < 10 || resolution > 100) {
            Debug.LogWarning("Grapher resolution out of bounds, resetting to minimum.", this);
            resolution = 10;
        }
        currentResolution = resolution;
        points = new ParticleSystem.Particle[resolution];
        float increment = 1f / (resolution - 1);
        for(int i = 0; i < resolution; i++){
            float x = i * increment;
            points[i].position = new Vector3(x, 0f, 0f);
            points[i].color = new Color(x, 0f, 0f);
            points[i].size = 0.1f;
        }
    }
  
    void Update () {
        if (currentResolution != resolution) {
            CreatePoints();
        }
        particleSystem.SetParticles(points, points.Length);
    }
}

如今只要改變分辨率的值就能重建圖表了。然而,你會注意到每當分辨率超出範圍,甚至是輸入的時候,控制檯都會彈出警告。咱們可使用Range屬性來告訴Unity編輯器使用滑塊來代替數字框。

因爲咱們只關注有效地輸入編輯,而且不會經過代碼來改變分辨率,因此如今能夠移除分辨率檢查了,固然,也許你會決定保留它。

1
2
[Range(10, 100)]
    public int resolution = 10;

 

有着分辨率範圍滑塊的Grapher1

如今該設置點在Y軸的位置了。簡單一點開始吧,把Y等於X。換句話說,咱們在可視化數學公式y = x,或者函數f(x) = x。爲了作到這一點,咱們須要循環全部的點,獲取它們的位置,使用X值計算Y值,而後設置新位置。一旦咱們使用for循環,就將執行每一個更新。

1
2
3
4
5
6
7
8
9
10
11
void Update () {
        if (currentResolution != resolution) {
            CreatePoints();
        }
        for (int i = 0; i < resolution; i++) {
            Vector3 p = points[i].position;
            p.y = p.x;
            points[i].position = p;
        }
        particleSystem.SetParticles(points, points.Length);
    }
 
函數 f(x) = x.

接下來把點的綠色份量設置的和Y位置同樣。因爲紅加綠會獲得黃,這將使得線從黑變黃。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void Update () {
        if (currentResolution != resolution) {
            CreatePoints();
        }
        for (int i = 0; i < resolution; i++) {
            Vector3 p = points[i].position;
            p.y = p.x;
            points[i].position = p;
            Color c = points[i].color;
            c.g = p.y;
            points[i].color = c;
        }
        particleSystem.SetParticles(points, points.Length);
    }
 
 
紅加綠獲得黃

或許你已經注意到了在播放狀態下改變代碼並回到Unity,你會看到NullReferenceException錯誤信息。這仍是由於從新加載時Unity沒有記錄私有點變量。

要解決這個問題,除了檢查分辨率,咱們能夠檢查點是否爲null。這將使咱們在編寫代碼時始終保持在播放模式,很是方便。注意這個檢查還能夠消除對Start方法的須要,因此能夠刪除它了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using UnityEngine;
  
public class Grapher1 : MonoBehaviour {
  
    [Range(10, 100)]
    public int resolution = 10;
  
    private int currentResolution;
    private ParticleSystem.Particle[] points;
  
    private void CreatePoints () {
        currentResolution = resolution;
        points = new ParticleSystem.Particle[resolution];
        float increment = 1f / (resolution - 1);
        for(int i = 0; i < resolution; i++){
            float x = i * increment;
            points[i].position = new Vector3(x, 0f, 0f);
            points[i].color = new Color(x, 0f, 0f);
            points[i].size = 0.1f;
        }
    }
  
    void Update () {
        if (currentResolution != resolution || points == null) {
            CreatePoints();
        }
        for (int i = 0; i < resolution; i++) {
            Vector3 p = points[i].position;
            p.y = p.x;
            points[i].position = p;
            Color c = points[i].color;
            c.g = p.y;
            points[i].color = c;
        }
        particleSystem.SetParticles(points, points.Length);
    }
}

原文連接:http://catlikecoding.com/unity/tutorials/graphs/

-----------------------------------------------------------------------------------------------

不知道做者的原始意圖是怎麼樣使用,

可是我以爲這個能夠用來開發點對點一類的特效,好比閃電鏈,捆仙繩之類的

先用曲線計算出路徑,而後依次設置特效點

相關文章
相關標籤/搜索