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