Unity自定義UI組件(三)餅圖篇

Unity自定義UI組件(三)餅圖篇

   博主在工作中曾經多次遇到過要計算並顯示一些數據佔比的功能,但是數值的顯示不夠直觀,然後在Unity商店中看到有人編寫過類似的UI插件,但是價格小貴,就萌發了自己編寫類似插件的衝動,第一次編寫是利用Image組件設置爲Filled類型時可實現扇形的功能進行組合,弊端特別明顯就是需要製作預製物,使得代碼量比較龐大,而且爲了實現一些炫酷的功能,還得引入緩衝池去避免不停生成扇形帶來的性能妥協,之後在瞭解了MaskableGraphic類型之後,利用底層繪製,可以避免由組件拼合的多種性能的妥協,而且極易移植,因爲只需要的一個腳本即可,下面會詳細講解如何繪製,並將附上源碼。

主要內容:

1.餅圖的基礎實現
2.餅圖百分比文字的顯示
3.餅圖文字的自適應
4.餅圖樣式自定義

實現效果:

餅圖

詳細設計:

1.餅圖的繪製過程:

1.1 獲取以某個點爲中心,固定半徑的圓上的點,再結合原點繪製三角面,可生成扇形;

圖一

  //計算圓上點的位置 Smooth代表圓的光滑程度,也就是餅圖被分爲多少等份
  int Smooth = 100;
  float perRadian = Matfh.PI * 2 / Smooth;//得到每份所佔弧度
  然後根據某一塊餅圖所佔的比例計算出它在圓周上相交的點,我們規定從餅圖右側中間位置開始,逆時針方向計算。見圖1:

  //比如繪製19%比例的扇形圖
  float radius = x;//半徑
  float startRadian = 0;
  Vector2 startPoint = new Vector2( radius,0 );
  for( int i = 0 ; i * perRadian < 0.19f * Mathf.PI * 2 ; i ++ )
  {
      float endRadian = startRadian + perRadian;
      Vector2 endPoint = new Vector2(Matfh.Cos(startRadian),Mathf.Sin(endRadian));
      startRadian = endRadian;
      startPoint = endPoint;
      //如上我們就可以利用startPoint點和endPoint和原點繪製出一個三角形,多個三角形的"積分"就是扇形了
  }
1.2 按輸入數據的數量,分爲若干扇形,一次繪製;
  //多個扇形的繪製就是我們只需要將以上的代碼寫到一個循環中就可以自動完成
  for( int i = 0 ; i < Count ; i ++ )
  {
      //執行1.1中類似的代碼
  }
1.3 在繪製時,爲UIVertex(UI頂點)傳入不同的顏色值,即可分類
  //在以上的步驟中我們已經能夠繪製出一個餅圖,但是我們應該如何爲不同的扇形附上不同的顏色值,我們需要在繪製三角面的時候會頂點設置顏色
  UIVertex vertex = new UIVertex
  {
      position = point ,
      color = color0 ,
  };
  //每次構造一個UI頂點的時候,給 color屬性賦值即可,因此我們就需要注意在構造餅圖類型的時候講顏色屬性添加爲一個Public字段,方便在這裏使用。
1.4 實現餅圖空心的原理是,繪製時不與原點組合三角面,原理見圖2

圖2

    繪製不在是與中心點直接構成三角形面進行繪製了,而是與小尺寸的圓的兩個新交點構成了一個矩形,因此得按照兩個三角形繪製,可以直接利用VertexHelper提供繪製矩形的接口直接繪製。
1.5 實現餅圖炸裂的原理,在每次繪製完一個扇形之後,隔一定弧度進行下一個扇形的繪製,這個弧度的大小可以自定義。就是在上面的繪製代碼的結尾處,將startRadian(繪製起始點)加一份炸裂效果產生的間隔的弧度:
  float boomRadian = x ; 
  for( int i = 0 ; i * perRadian < 0.19f * Mathf.PI * 2 ; i ++ )
  {
      //P-CODE
      startRadian += boomRadian;
  }

2. 文字的添加:

2.1 文字應該顯示在折線的左端或者右端,計算出折線的左端或者右端的點的位置,就可以確定文字的位置,並且確定文字應該左對齊,還是右對齊

圖3

  //如果需要繪製百分比的文字,則需要我們在繪製扇形的時候記錄下扇形中點所對應的弧度,開始繪製的第一個其實弧度加上扇形弧度的1/2
  float middleRadian = startRadian + radian / 2.0f;
  Vector2 point = new Vector2(Mathf.Cos(middleRadian),Mathf.Sin(middleRadian)) * radius;
  //這時我們還需要記錄下它應該靠左顯示還是靠右顯示,所有相對於中心點(0,0)爲正在右,反則在左。
2.2 折線的繪製應該在扇形弧度的中間值處取一點(就是在2.1中獲取的中點),然後在同一方向的某個距離上取的第二個點,然後在第二個點的同一水平線上取第三個點來繪製折線
  Vector2 secondPoint = new Vector2(Mathf.Cos(middleRadian),Mathf.Sin(middleRadian)) * (radius + brokenLineLenght);
  //第三個點可以根據是在左側或者是右側直接水平挪動一定的值即可,比如在右側
  Vector2 thridPoint = secondPoint + new Vector2(extralenght,0);
  //同理三個點,兩兩繪製直線即可
2.3 文字自適應的方法在函數圖篇中已經講解過,方法在代碼中也有,不在贅述。

拓展方向:

   在這個工具做完之後我才思考過一個問題,這樣做出的來的餅圖暫時還不能和鼠標直接發生交互,但是如果我們想要更加炫酷的效果,比如鼠標移動到某一個扇形上,扇形變大顯示等就沒法實現嗎?博主在後續的文章會提出可行的解決方案,希望大家也能夠參與進來一起思考,看看大家有什麼更好的想法。
好了以後的博文就不會像之前的博文一樣把所有的源代碼全部粘貼進去了,以後會只針對關鍵部分用僞代碼進行簡單的講解,如果能夠看懂,希望可以自己先手動編寫,當然也可以下載我的全部源碼。

下載鏈接

1.CSDN下載:

http://download.csdn.net/detail/qq_29579137/9835230

2.GitHub下載:

https://github.com/ll4080333

3.CSDN博客:

http://blog.csdn.net/qq_29579137

如果你覺我的文章有可用之處,歡迎點贊,如果有不足,歡迎評論留言並指出。關注我的博客第一時間獲取後續更新內容。

==轉載表明出處==

發佈了30 篇原創文章 · 獲贊 194 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章