顯示具有 ellipse 標籤的文章。 顯示所有文章
顯示具有 ellipse 標籤的文章。 顯示所有文章

2016年5月21日 星期六

2D ellipse mesh in Unity

這篇文章講的是在 Unity 中以 script 建立 2D 橢圓。


Project view 中是有一個 Circle Sprite,

但那是一個 sprite,實際上仍是矩形,裡面放一個圓形的圖案而已,不是我要的。

一個真正的 2D ellipse mesh 它的外圍形狀是橢圓的,我們在實做時,把多個頂點繞著圓心一圈組成。示意圖配合公式,像是這樣:

只要在code裡面產生很多三角形(紅色那些三角形),繞一圈,就可以組成一個橢圓。


Unity 裡面,每個物體都會由多個 Mesh 組成,而每個 Mesh 再由多個三角形組成。每個三角形有三個頂點,每個頂點上有一些屬性,像是座標、UV、法線向量...。不過這篇文章只示範產生座標的方法,而法線讓 unity 自動計算,至於 UV 這個用來配置材質的東西,以後再說。


在兜橢圓時,三角形的數量越多,看起來就會越圓。底下這個是5個三角形組成的橢圓:

是不像橢圓,但比較好解釋,因為上面的藍色線的方向是有意義的。Unity 中的三角形,它的三個頂點在連起來時,順序必須是順時針方向,否則看不到。如果你畫了三角形卻看不到,很可能Camera 照到它的背面了,可以去三角形的背面看看。


可動的code:
 1 using UnityEngine;
 2 using UnityEngine.UI;
 3 using System.Collections;
 4 using System.Collections.Generic;
 5 using System;
 6 using Random = UnityEngine.Random;
 7 
 8 using UnityEngine.Events;
 9 using UnityEngine.EventSystems;
10 
11 
12 public class test : MonoBehaviour
13 {
14   void Start ()
15   {
16     Ellipse2D ellipse1 = new Ellipse2D (0, 0, 0, 1, 1);
17     Ellipse2D ellipse2 = new Ellipse2D (4, 0, 0, 2, 3);
18     Ellipse2D ellipse3 = new Ellipse2D (2, 5, 0, 3, 2);
19   }
20 }
21 
22 
23 public class Ellipse2D
24 {
25   public GameObject gameObject;
26 
27   public Ellipse2D (
28     float   x,
29     float   y,
30     float   z,
31     float   semiMajor,
32     float   semiMinor
33   )
34   {
35     gameObject = new GameObject ("Ellipse2D");
36 
37     Vector3 center = new Vector3 (x, y, z);
38     gameObject.transform.localPosition = center;
39 
40     Renderer renderer = gameObject.AddComponent<MeshRenderer> ();
41     renderer.material = new Material (Shader.Find ("Diffuse"));
42 
43     // 建立 mesh. 一個 mesh 上可以有多個三角形
44     Mesh mesh = new Mesh ();
45 
46     // 定義每個 ellipse 上由 30 個三角形構成
47     int triangleCount = 30; // 10
48 
49     float dTh = (2 * Mathf.PI / triangleCount);
50 
51     // 存放頂點
52     Vector3[] vertices = new Vector3[triangleCount * 3];
53 
54     // 每個 for index 會計算一個三角形中的三個頂點座標
55     for (int index = 0; index < triangleCount; index++) {
56 
57       // triangle vertex 1
58       vertices [index * 3] = new Vector3 (0, 0, 0);
59 
60       // triangle vertex 2
61       float th1 = dTh * (index + 1);
62       vertices [index * 3 + 1] = new Vector3 (semiMajor * Mathf.Cos (th1), semiMinor * Mathf.Sin (th1), 0);
63 
64       // triangle vertex 3
65       float th2 = dTh * (index);
66       vertices [index * 3 + 2] = new Vector3 (semiMajor * Mathf.Cos (th2), semiMinor * Mathf.Sin (th2), 0);
67     }
68 
69     // 蒐集所有頂點給 mesh
70     mesh.vertices = vertices;
71 
72     // 指定三角形的繞法
73     int[] triangles = new int[triangleCount * 3];
74     for (int i = 0; i < triangleCount * 3; i++) {
75       triangles [i] = i;
76     }
77 
78     mesh.triangles = triangles;
79 
80     // 自動計算法線
81     mesh.RecalculateNormals ();
82     mesh.RecalculateBounds ();
83     mesh.Optimize ();
84 
85     // 最後對物件添上 MeshFilter component, 指定 mesh 給他。
86     MeshFilter mf = gameObject.AddComponent<MeshFilter> ();
87     mf.mesh = mesh;
88   }
89 }
90 

圖看起來像這樣:




Reference:
. http://docs.unity3d.com/ScriptReference/Mesh.html