C# Unity3d中的圆锥形平截头体

C# Unity3d中的圆锥形平截头体,c#,unity3d,runtime,frustum,C#,Unity3d,Runtime,Frustum,我正在帮助我的朋友做他的研究项目,为此我们需要一个3d平截体,能够在运行时设置上圆表面和下圆表面的直径,你能告诉我怎么做吗?我正在考虑获取edgex/顶点的数组,这些顶点与顶部和底部的中心顶点相连,并更改它们的坐标,也许有一种更简单的方法可以做到这一点?要创建具有动态大小的圆锥体平截头体,您可以从中使用脚本 由于在开始时只创建一次网格,因此您可以准确地知道哪些顶点是顶部和底部平面的顶点,以便以后可以轻松地动态更改它们 有点像 public class DynamicConicalFrustum

我正在帮助我的朋友做他的研究项目,为此我们需要一个3d平截体,能够在运行时设置上圆表面和下圆表面的直径,你能告诉我怎么做吗?我正在考虑获取edgex/顶点的数组,这些顶点与顶部和底部的中心顶点相连,并更改它们的坐标,也许有一种更简单的方法可以做到这一点?

要创建具有动态大小的圆锥体平截头体,您可以从中使用脚本

由于在开始时只创建一次网格,因此您可以准确地知道哪些顶点是顶部和底部平面的顶点,以便以后可以轻松地动态更改它们

有点像

public class DynamicConicalFrustum : MonoBehaviour
{
    [SerializeField] private MeshFilter meshFilter;
    [SerializeField] private MeshCollider meshCollider;

    [Header("Settings")]
    [SerializeField] private float _height = 1f;
    [SerializeField] private float _bottomRadius = .25f;
    [SerializeField] private float _topRadius = .05f;
    [SerializeField] private int nbSides = 18;

    private Mesh mesh;
    const float _2pi = Mathf.PI * 2f;
    private Vector3[] vertices;

    private void Awake()
    {
        if (!meshFilter && !TryGetComponent<MeshFilter>(out meshFilter))
        {
            meshFilter = gameObject.AddComponent<MeshFilter>();
        }

        if(!GetComponent<MeshRenderer>())
        {
            var mr = gameObject.AddComponent<MeshRenderer>();
            mr.material = new Material(Shader.Find("Standard"));
        }

        if (!meshCollider)
            meshCollider = GetComponent<MeshCollider>();

        mesh = meshFilter.mesh;

        if (!mesh)
        {
            mesh = new Mesh();
        }

        meshFilter.mesh = mesh;
        if (meshCollider)
            meshCollider.sharedMesh = mesh;

        RecreateFrustum(_height,_bottomRadius,_topRadius);
    }

#if UNITY_EDITOR
    private void OnValidate()
    {
        if (Application.isPlaying)
        {
            Awake();
        }
    }
#endif

    public void RecreateFrustum(float height, float bottomRadius, float topRadius)
    {
        mesh.Clear();

        int nbVerticesCap = nbSides + 1;
        #region Vertices

        // bottom + top + sides
        vertices = new Vector3[nbVerticesCap + nbVerticesCap + nbSides  * 2 + 2];

        // Bottom cap
        vertices[0] = new Vector3(0f, 0f, 0f);
        for(var idx = 1; idx <= nbSides; idx++)
        {
            float rad = (float)(idx ) / nbSides * _2pi;
            vertices[idx ] = new Vector3(Mathf.Cos(rad) * bottomRadius, 0f, Mathf.Sin(rad) * bottomRadius);
        }

        // Top cap
        vertices[nbSides + 1] = new Vector3(0f, height, 0f);
        for(var idx = nbSides + 2; idx <= nbSides * 2 + 1; idx++)
        { 
            float rad = (float)(idx - nbSides - 1) / nbSides * _2pi;
            vertices[idx] = new Vector3(Mathf.Cos(rad) * topRadius, height, Mathf.Sin(rad) * topRadius);
        }

        // Sides
        int v = 0;
        for(var idx = nbSides * 2 + 2; idx <= vertices.Length - 4; idx+=2)
        { 
            float rad = (float)v / nbSides * _2pi;
            vertices[idx] = new Vector3(Mathf.Cos(rad) * topRadius, height, Mathf.Sin(rad) * topRadius);
            vertices[idx + 1] = new Vector3(Mathf.Cos(rad) * bottomRadius, 0, Mathf.Sin(rad) * bottomRadius);
            v++;
        }
        vertices[vertices.Length - 2] = vertices[nbSides * 2 + 2];
        vertices[vertices.Length - 1] = vertices[nbSides * 2 + 3];
        #endregion

        #region Triangles
        int nbTriangles = nbSides + nbSides + nbSides * 2;
        int[] triangles = new int[nbTriangles * 3 + 3];

        // Bottom cap
        int tri = 0;
        int i = 0;
        while (tri < nbSides - 1)
        {
            triangles[i] = 0;
            triangles[i + 1] = tri + 1;
            triangles[i + 2] = tri + 2;
            tri++;
            i += 3;
        }
        triangles[i] = 0;
        triangles[i + 1] = tri + 1;
        triangles[i + 2] = 1;
        tri++;
        i += 3;

        // Top cap
        //tri++;
        while (tri < nbSides * 2)
        {
            triangles[i] = tri + 2;
            triangles[i + 1] = tri + 1;
            triangles[i + 2] = nbVerticesCap;
            tri++;
            i += 3;
        }

        triangles[i] = nbVerticesCap + 1;
        triangles[i + 1] = tri + 1;
        triangles[i + 2] = nbVerticesCap;
        tri++;
        i += 3;
        tri++;

        // Sides
        while (tri <= nbTriangles)
        {
            triangles[i] = tri + 2;
            triangles[i + 1] = tri + 1;
            triangles[i + 2] = tri + 0;
            tri++;
            i += 3;

            triangles[i] = tri + 1;
            triangles[i + 1] = tri + 2;
            triangles[i + 2] = tri + 0;
            tri++;
            i += 3;
        }
        #endregion

        mesh.vertices = vertices;
        mesh.triangles = triangles;

        mesh.RecalculateBounds();
        mesh.RecalculateNormals();
        mesh.RecalculateTangents();
        mesh.Optimize();
    }
}
公共类动态信任:单行为
{
[SerializeField]专用MeshFilter MeshFilter;
[SerializeField]专用MeshCollider MeshCollider;
[标题(“设置”)]
[Field]专用浮子_高度=1f;
[SerializeField]专用浮点数_bottomRadius=.25f;
[SerializeField]专用浮点_topRadius=.05f;
[SerializeField]private int nbSides=18;
私有网格;
常数浮点_2pi=Mathf.PI*2f;
私有向量3[]个顶点;
私人空间
{
if(!meshFilter&&!TryGetComponent(out meshFilter))
{
meshFilter=gameObject.AddComponent();
}
如果(!GetComponent())
{
var mr=gameObject.AddComponent();
mr.material=新材质(Shader.Find(“标准”));
}
if(!meshCollider)
meshCollider=GetComponent();
mesh=meshFilter.mesh;
如果(!网格)
{
网格=新网格();
}
meshFilter.mesh=网格;
if(网格碰撞器)
meshCollider.sharedMesh=网格;
重新创建平截头体(_高度,_底部半径,_顶部半径);
}
#如果统一编辑器
私有void OnValidate()
{
if(Application.isPlaying)
{
觉醒();
}
}
#恩迪夫
公共空心重新创建平截头体(浮动高度、浮动底部半径、浮动顶部半径)
{
mesh.Clear();
int nbVerticesCap=nbSides+1;
#区域顶点
//底部+顶部+侧面
顶点=新矢量3[nbVerticesCap+nbVerticesCap+nbSides*2+2];
//底盖
顶点[0]=新向量3(0f,0f,0f);
对于(var idx=1;idx在Unity中,“平截体”通常指相机平截体。