本文由Aoi翻譯,轉載請註明出處。文章來自於catlikecoding,原文做者介紹了Unity製做圖表、可視化數據的方法。更多的名詞解釋內容,請點擊末尾的「原文連接」查看。html
介紹數組
這個教程裏,咱們在Unity 4裏用C#腳原本展現日趨複雜的圖表。你將學會:編輯器
假設你已經對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 Awake, Emission,以及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);
}
|
就是這樣,如今咱們獲得了一個沿着X軸由黑到紅的點線。顯示多少點取決於分辨率的值。
如今,只有在圖表初始化的時候考慮分辨率。播放模式下更新值不起任何做用。如今來修改一下。
檢測分辨率的一個簡單方法是存儲兩次,而後常常檢查這兩個值是否仍然同樣。若是在某些點不同,咱們就要重建圖表。爲此須要建立一個私有變量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;
|
如今該設置點在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);
}
|
接下來把點的綠色份量設置的和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/
-----------------------------------------------------------------------------------------------
不知道做者的原始意圖是怎麼樣使用,
可是我以爲這個能夠用來開發點對點一類的特效,好比閃電鏈,捆仙繩之類的
先用曲線計算出路徑,而後依次設置特效點