查看: 1652|回复: 2
打印 上一主题 下一主题

untiy3d创建锥体代码

[复制链接]

2508

主题

2

听众

3万

积分

资深设计师

Rank: 7Rank: 7Rank: 7

纳金币
32806
精华
12

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

跳转到指定楼层
楼主
发表于 2012-8-3 17:49:02 |只看该作者 |倒序浏览
功能描述:

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 ***ncated 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.
Note it is inevitable that a ***e cone (one of the radii == 0) cannot be rendered completely smooth, and will show facetting artifacts.
使用方法:

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

using UnityEngine;
using UnityEditor;

using System.Collections;
// a static method to create a cone primitive (so far no end caps)

// the top center is placed at (0/0/0)

// the bottom center is placed at (0/0/length)

// if either one of the radii is 0, the result will be a cone, otherwise a ***ncated cone

// note you will get inevitable breaks in the smooth shading at cone tips

// Author: Wolfram Kresse

public class CreateCone : ScriptableWizard {
    public int numVertices = 10;

    public float radiusTop = 0f;

    public float radiusBottom = 1f;

    public float length = 1f;

    public float openingAngle = 0f; // if >0, create a cone with this angle by setting radiusTop to 0, and adjust radiusBottom according to length;

    public bool outside = ***e;

    public bool inside = false;

    public bool addCollider = false;

   

    [MenuItem ("GameObject/Create Other/Cone")]

    static void CreateWizard()

    {

        ScriptableWizard.DisplayWizard("Create Cone", typeof(CreateCone));

    }

   

    void OnWizardCreate(){

        GameObject newCone=new GameObject("Cone");

        // can't access Camera.current

        //newCone.transform.position = Camera.current.transform.position + Camera.current.transform.forward * 5.0f;

        int multiplier=(outside?1:0)+(inside?1:0);

        int offset=(outside&&inside?2*numVertices:0);

        Vector3[] vertices=new Vector3[2*multiplier*numVertices]; // 0..n-1: top, n..2n-1: bottom

        Vector3[] normals=new Vector3[2*multiplier*numVertices];

        Vector2[] uvs=new Vector2[2*multiplier*numVertices];

        int[] tris;

        Mesh mesh=new Mesh();
        if(openingAngle>0&&openingAngle<180){

            radiusTop=0;

            radiusBottom=length*Mathf.Tan(openingAngle*Mathf.Deg2Rad/2);

        }

        float slope=Mathf.Atan((radiusBottom-radiusTop)/length); // (rad difference)/height

        float slopeSin=Mathf.Sin(slope);

        float slopeCos=Mathf.Cos(slope);

        int i;
        for(i=0;i<numVertices;i++){

            float angle=2*Mathf.PI*i/numVertices;

            float angleSin=Mathf.Sin(angle);

            float angleCos=Mathf.Cos(angle);

            float angleHalf=2*Mathf.PI*(i+0.5f)/numVertices; // for degenerated normals at cone tips

            float angleHalfSin=Mathf.Sin(angleHalf);

            float angleHalfCos=Mathf.Cos(angleHalf);
            vertices=new Vector3(radiusTop*angleCos,radiusTop*angleSin,0);

            vertices[i+numVertices]=new Vector3(radiusBottom*angleCos,radiusBottom*angleSin,length);
            if(radiusTop==0)

                normals=new Vector3(angleHalfCos*slopeCos,angleHalfSin*slopeCos,-slopeSin);

            else

                normals=new Vector3(angleCos*slopeCos,angleSin*slopeCos,-slopeSin);

            if(radiusBottom==0)

                normals[i+numVertices]=new Vector3(angleHalfCos*slopeCos,angleHalfSin*slopeCos,-slopeSin);

            else

                normals[i+numVertices]=new Vector3(angleCos*slopeCos,angleSin*slopeCos,-slopeSin);
            uvs=new Vector2(1.0f*i/numVertices,1);

            uvs[i+numVertices]=new Vector2(1.0f*i/numVertices,0);
            if(outside&&inside){

                // vertices and uvs are identical on inside and outside, so just copy

                vertices[i+2*numVertices]=vertices;

                vertices[i+3*numVertices]=vertices[i+numVertices];

                uvs[i+2*numVertices]=uvs;

                uvs[i+3*numVertices]=uvs[i+numVertices];

            }

            if(inside){

                // invert normals

                normals[i+offset]=-normals;

                normals[i+numVertices+offset]=-normals[i+numVertices];

            }

        }

        MeshFilter mf=newCone.AddComponent<MeshFilter>();

        mesh.vertices = vertices;

        mesh.normals = normals;  

        mesh.uv = uvs;
        // create triangles

        // here we need to take care of point order, depending on inside and outside

        int cnt=0;

        if(radiusTop==0){

            // top cone

            tris=new int[numVertices*3*multiplier];

            if(outside)

                for(i=0;i<numVertices;i++){

                    tris[cnt++]=i+numVertices;

                    tris[cnt++]=i;

                    if(i==numVertices-1)

                        tris[cnt++]=numVertices;

                    else

                        tris[cnt++]=i+1+numVertices;

                }

            if(inside)

                for(i=offset;i<numVertices+offset;i++){

                    tris[cnt++]=i;

                    tris[cnt++]=i+numVertices;

                    if(i==numVertices-1+offset)

                        tris[cnt++]=numVertices+offset;

                    else

                        tris[cnt++]=i+1+numVertices;

                }

        }else if(radiusBottom==0){

            // bottom cone

            tris=new int[numVertices*3*multiplier];

            if(outside)

                for(i=0;i<numVertices;i++){

                    tris[cnt++]=i;

                    if(i==numVertices-1)

                        tris[cnt++]=0;

                    else

                        tris[cnt++]=i+1;

                    tris[cnt++]=i+numVertices;

                }

            if(inside)

                for(i=offset;i<numVertices+offset;i++){

                    if(i==numVertices-1+offset)

                        tris[cnt++]=offset;

                    else

                        tris[cnt++]=i+1;

                    tris[cnt++]=i;

                    tris[cnt++]=i+numVertices;

                }

        }else{

            // ***ncated cone

            tris=new int[numVertices*6*multiplier];

            if(outside)

                for(i=0;i<numVertices;i++){

                    int ip1=i+1;

                    if(ip1==numVertices)

                        ip1=0;
                    tris[cnt++]=i;

                    tris[cnt++]=ip1;

                    tris[cnt++]=i+numVertices;
                    tris[cnt++]=ip1+numVertices;

                    tris[cnt++]=i+numVertices;

                    tris[cnt++]=ip1;

                }

            if(inside)

                for(i=offset;i<numVertices+offset;i++){

                    int ip1=i+1;

                    if(ip1==numVertices+offset)

                        ip1=offset;
                    tris[cnt++]=ip1;

                    tris[cnt++]=i;

                    tris[cnt++]=i+numVertices;
                    tris[cnt++]=i+numVertices;

                    tris[cnt++]=ip1+numVertices;

                    tris[cnt++]=ip1;

                }

        }

        mesh.triangles = tris;   

        

        mf.mesh = mesh;
        newCone.AddComponent<MeshRenderer>();
        if(addCollider){

            MeshCollider mc=newCone.AddComponent<MeshCollider>();

            mc.sharedMesh=mf.sharedMesh;

        }
        Selection.activeObject = newCone;

    }
}
分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

2508

主题

2

听众

3万

积分

资深设计师

Rank: 7Rank: 7Rank: 7

纳金币
32806
精华
12

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

沙发
发表于 2012-8-3 17:54:09 |只看该作者
我爱纳金网~www.narkii.com
回复

使用道具 举报

2317

主题

54

听众

2万

积分

资深设计师

Rank: 7Rank: 7Rank: 7

纳金币
20645
精华
62

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

板凳
发表于 2012-12-30 04:16:07 |只看该作者
学习了,虽然还是有难度,谢谢楼主的用心
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备2021016425号-2/3

GMT+8, 2025-7-21 15:11 , Processed in 0.185665 second(s), 29 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部