【转载】在Unity编辑器中创建圆锥体(不借助3DS MAX或Maya等建模工具,创建几何体)

我的注:生成几何体的主要思路是在自建mesh中设置顶点、UV坐标、三角形等信息

以下转自:http://wiki.unity3d.com/index.php?title=CreateCone

CreateCone

 
 

Author: Wolfram Kresse

Description

This editor script creates a cone with the specified tessellation (=number of vertices), top radius, bottom radius, and length. With top radius == bottom radius, the result is a cylinder. With none of the radii == 0, the result is a truncated cone. So far the resulting cone has no end caps, but you can create caps on your own by using a cone with one radius==0 and length==0.

The resulting mesh will be added as an asset to Assets/Editor, so it can be used in prefabs etc.

Note it is inevitable that a true cone (one of the radii == 0) cannot be rendered completely smooth, and will show facetting artifacts.

Usage

Place this script as "CreateCone.cs" in YourProject/Assets/Editor and a menu item will automatically appear in the "GameObject/Create Other" menu after it is compiled.

Num Vertices is the number of vertices each end will have.
Radius Top is the radius at the top. The center point will be located at (0/0/0).
Radius Bottom is the radius at the bottom. The center point will be located at (0/0/Length).
Length is the number of world units long the plane will be (+Z direction).
Opening Angle If this is >0, the top radius is set to 0, and the bottom radius is computed depending on the length, so that the given opening angle is created.
Outside defines whether the outside is visible (default).
Inside defines whether the inside is visible. Set both outside and inside to create a double-sided primitive.
Add Collider creates a matching mesh collider for the cone if checked.

 

C# - CreateCone.cs

  1 using UnityEngine;
  2 using UnityEditor;
  3 using System.Collections;
  4  
  5 // an Editor method to create a cone primitive (so far no end caps)
  6 // the top center is placed at (0/0/0)
  7 // the bottom center is placed at (0/0/length)
  8 // if either one of the radii is 0, the result will be a cone, otherwise a truncated cone
  9 // note you will get inevitable breaks in the smooth shading at cone tips
 10 // note the resulting mesh will be created as an asset in Assets/Editor
 11 // Author: Wolfram Kresse
 12 public class CreateCone : ScriptableWizard {
 13  
 14     public int numVertices = 10;
 15     public float radiusTop = 0f;
 16     public float radiusBottom = 1f;
 17     public float length = 1f;
 18     public float openingAngle = 0f; // if >0, create a cone with this angle by setting radiusTop to 0, and adjust radiusBottom according to length;
 19     public bool outside = true;
 20     public bool inside = false;
 21     public bool addCollider = false;
 22  
 23     [MenuItem ("GameObject/Create Other/Cone")]
 24     static void CreateWizard()
 25     {
 26         ScriptableWizard.DisplayWizard("Create Cone", typeof(CreateCone));
 27     }
 28  
 29     void OnWizardCreate(){
 30         GameObject newCone=new GameObject("Cone");
 31         if(openingAngle>0&&openingAngle<180){
 32             radiusTop=0;
 33             radiusBottom=length*Mathf.Tan(openingAngle*Mathf.Deg2Rad/2);
 34         }
 35         string meshName = newCone.name + numVertices + "v" + radiusTop + "t" + radiusBottom + "b" + length + "l" + length + (outside?"o":"") + (inside?"i":"");
 36         string meshPrefabPath = "Assets/Editor/" + meshName + ".asset";
 37         Mesh mesh = (Mesh)AssetDatabase.LoadAssetAtPath(meshPrefabPath, typeof(Mesh));
 38         if(mesh==null){
 39             mesh=new Mesh();
 40             mesh.name=meshName;
 41             // can't access Camera.current
 42             //newCone.transform.position = Camera.current.transform.position + Camera.current.transform.forward * 5.0f;
 43             int multiplier=(outside?1:0)+(inside?1:0);
 44             int offset=(outside&&inside?2*numVertices:0);
 45             Vector3[] vertices=new Vector3[2*multiplier*numVertices]; // 0..n-1: top, n..2n-1: bottom
 46             Vector3[] normals=new Vector3[2*multiplier*numVertices];
 47             Vector2[] uvs=new Vector2[2*multiplier*numVertices];
 48             int[] tris;
 49             float slope=Mathf.Atan((radiusBottom-radiusTop)/length); // (rad difference)/height
 50             float slopeSin=Mathf.Sin(slope);
 51             float slopeCos=Mathf.Cos(slope);
 52             int i;
 53  
 54             for(i=0;i<numVertices;i++){
 55                 float angle=2*Mathf.PI*i/numVertices;
 56                 float angleSin=Mathf.Sin(angle);
 57                 float angleCos=Mathf.Cos(angle);
 58                 float angleHalf=2*Mathf.PI*(i+0.5f)/numVertices; // for degenerated normals at cone tips
 59                 float angleHalfSin=Mathf.Sin(angleHalf);
 60                 float angleHalfCos=Mathf.Cos(angleHalf);
 61  
 62                 vertices[i]=new Vector3(radiusTop*angleCos,radiusTop*angleSin,0);
 63                 vertices[i+numVertices]=new Vector3(radiusBottom*angleCos,radiusBottom*angleSin,length);
 64  
 65                 if(radiusTop==0)
 66                     normals[i]=new Vector3(angleHalfCos*slopeCos,angleHalfSin*slopeCos,-slopeSin);
 67                 else
 68                     normals[i]=new Vector3(angleCos*slopeCos,angleSin*slopeCos,-slopeSin);
 69                 if(radiusBottom==0)
 70                     normals[i+numVertices]=new Vector3(angleHalfCos*slopeCos,angleHalfSin*slopeCos,-slopeSin);
 71                 else
 72                     normals[i+numVertices]=new Vector3(angleCos*slopeCos,angleSin*slopeCos,-slopeSin);
 73  
 74                 uvs[i]=new Vector2(1.0f*i/numVertices,1);
 75                 uvs[i+numVertices]=new Vector2(1.0f*i/numVertices,0);
 76  
 77                 if(outside&&inside){
 78                     // vertices and uvs are identical on inside and outside, so just copy
 79                     vertices[i+2*numVertices]=vertices[i];
 80                     vertices[i+3*numVertices]=vertices[i+numVertices];
 81                     uvs[i+2*numVertices]=uvs[i];
 82                     uvs[i+3*numVertices]=uvs[i+numVertices];
 83                 }
 84                 if(inside){
 85                     // invert normals
 86                     normals[i+offset]=-normals[i];
 87                     normals[i+numVertices+offset]=-normals[i+numVertices];
 88                 }
 89             }
 90             mesh.vertices = vertices;
 91             mesh.normals = normals;        
 92             mesh.uv = uvs;
 93  
 94             // create triangles
 95             // here we need to take care of point order, depending on inside and outside
 96             int cnt=0;
 97             if(radiusTop==0){
 98                 // top cone
 99                 tris=new int[numVertices*3*multiplier];
100                 if(outside)
101                     for(i=0;i<numVertices;i++){
102                         tris[cnt++]=i+numVertices;
103                         tris[cnt++]=i;
104                         if(i==numVertices-1)
105                             tris[cnt++]=numVertices;
106                         else
107                             tris[cnt++]=i+1+numVertices;
108                     }
109                 if(inside)
110                     for(i=offset;i<numVertices+offset;i++){
111                         tris[cnt++]=i;
112                         tris[cnt++]=i+numVertices;
113                         if(i==numVertices-1+offset)
114                             tris[cnt++]=numVertices+offset;
115                         else
116                             tris[cnt++]=i+1+numVertices;
117                     }
118             }else if(radiusBottom==0){
119                 // bottom cone
120                 tris=new int[numVertices*3*multiplier];
121                 if(outside)
122                     for(i=0;i<numVertices;i++){
123                         tris[cnt++]=i;
124                         if(i==numVertices-1)
125                             tris[cnt++]=0;
126                         else
127                             tris[cnt++]=i+1;
128                         tris[cnt++]=i+numVertices;
129                     }
130                 if(inside)
131                     for(i=offset;i<numVertices+offset;i++){
132                         if(i==numVertices-1+offset)
133                             tris[cnt++]=offset;
134                         else
135                             tris[cnt++]=i+1;
136                         tris[cnt++]=i;
137                         tris[cnt++]=i+numVertices;
138                     }
139             }else{
140                 // truncated cone
141                 tris=new int[numVertices*6*multiplier];
142                 if(outside)
143                     for(i=0;i<numVertices;i++){
144                         int ip1=i+1;
145                         if(ip1==numVertices)
146                             ip1=0;
147  
148                         tris[cnt++]=i;
149                         tris[cnt++]=ip1;
150                         tris[cnt++]=i+numVertices;
151  
152                         tris[cnt++]=ip1+numVertices;
153                         tris[cnt++]=i+numVertices;
154                         tris[cnt++]=ip1;
155                     }
156                 if(inside)
157                     for(i=offset;i<numVertices+offset;i++){
158                         int ip1=i+1;
159                         if(ip1==numVertices+offset)
160                             ip1=offset;
161  
162                         tris[cnt++]=ip1;
163                         tris[cnt++]=i;
164                         tris[cnt++]=i+numVertices;
165  
166                         tris[cnt++]=i+numVertices;
167                         tris[cnt++]=ip1+numVertices;
168                         tris[cnt++]=ip1;
169                     }
170             }
171             mesh.triangles = tris;        
172             AssetDatabase.CreateAsset(mesh, meshPrefabPath);
173             AssetDatabase.SaveAssets();
174         }
175  
176         MeshFilter mf=newCone.AddComponent<MeshFilter>();
177         mf.mesh = mesh;
178  
179         newCone.AddComponent<MeshRenderer>();
180  
181         if(addCollider){
182             MeshCollider mc=newCone.AddComponent<MeshCollider>();
183             mc.sharedMesh=mf.sharedMesh;
184         }
185  
186         Selection.activeObject = newCone;
187     }
188 }

 

posted on 2017-11-16 22:45  重新定义自己  阅读(2321)  评论(0)    收藏  举报

导航