Unity代码绘制扇形,环形,扇环

上效果:

上代码:

using UnityEngine;


/// <summary>
/// 绘制 扇形,环形,扇环
/// </summary>
[ExecuteInEditMode]
[RequireComponent(typeof(MeshRenderer), typeof(MeshFilter))]
public class AnnularSector : MonoBehaviour
{
    public float OuterRadius = 6; //外半径  
    public float InnerRadius = 3; //外半径  
    public float Height = 3; //高度  
    public float angleDegree = 360; //扇形或扇面的角度
    public int Segments = 20; //分割数  
    private MeshFilter meshFilter;

    void OnEnable()
    {
        UpdateShape();
    }
    
    public void SetShape(BoundingShape shape)
    {
        angleDegree = shape.Angle;
        Height = shape.Height;
        OuterRadius = shape.Radius;
        InnerRadius = shape.Length;
        UpdateShape();
    }
    void UpdateShape()
    {
        meshFilter = GetComponent<MeshFilter>();
        meshFilter.mesh = CreateMesh(OuterRadius, InnerRadius, angleDegree, Segments);
    }

    Mesh CreateMesh(float outerRadius, float innerRadius, float angledegree, int segments)
    {
        float angleRad = Mathf.Deg2Rad * angledegree;
        float angleStart = -angleRad / 2; // 扇形开始角度
        float endStart = angleRad / 2; // 扇形结束角度
        float angledelta = angleRad / segments;

        //扇环两条弧上, 一条弧上顶点的数量
        int vertexCount = segments + 1; 
        
        // 四条弧总共的顶点数量
        Vector3[] vertex = new Vector3[vertexCount * 2 * 2];
        // 上表面两条弧的顶点
        // 大扇形弧上的顶点
        float angleCur = angleStart;
        for (int i = 0; i < vertexCount; i++)
        {
            float cosA = Mathf.Cos(angleCur);
            float sinA = Mathf.Sin(angleCur);
            vertex[i] = new Vector3(outerRadius * cosA, 0, outerRadius * sinA);
            angleCur += angledelta; // 从左到右
        }
        // 小扇形弧上的顶点
        angleCur = angleStart;
        for (int i = vertexCount; i < vertexCount * 2; i++)
        {
            float cosA = Mathf.Cos(angleCur);
            float sinA = Mathf.Sin(angleCur);
            vertex[i] = new Vector3(innerRadius * cosA, 0, innerRadius * sinA);
            angleCur += angledelta; // 从左到右
        }
        // 下表面两条弧的顶点
        for (int i = vertexCount * 2; i < vertexCount * 4 ; i++)
        {
            vertex[i] = vertex[i - vertexCount * 2] - Vector3.up * Height;
        }
        
        // 上,左,前,表面三角形数量
        int topTriangleCount = segments * 2; 
        int leftTriangleCount = 2;
        int frontTriangleCount = segments * 2;
        
        // 全部数量
        int triangleCount = (topTriangleCount + leftTriangleCount + frontTriangleCount) * 2;
        // 全部三角形顶点索引
        int[] triangles = new int[triangleCount * 3]; // 三角形顶点

        // 上, 下表面三角形,顶点索引
        int verticeIndex = 0;
        int startTriangleIndex = 0;
        for (int i = startTriangleIndex; i < topTriangleCount * 2 * 3 ; i += 12)
        {
            //上表面
            int startIndex = verticeIndex;
            // 逆时针, 第一个三角形
            triangles[i] = startIndex;
            triangles[i + 1] = vertexCount + startIndex + 1;
            triangles[i + 2] = startIndex + 1;
            // 逆时针, 第二个三角形
            triangles[i + 3] = startIndex;
            triangles[i + 4] = vertexCount + startIndex;
            triangles[i + 5] = vertexCount + startIndex + 1;
            
            // 下表面
            startIndex = verticeIndex + vertexCount * 2;
            // 顺时针, 第一个三角形
            triangles[i + 6] = startIndex;
            triangles[i + 7] = startIndex + 1;
            triangles[i + 8] = vertexCount + startIndex + 1; 
            // 顺时针, 第二个三角形
            triangles[i + 9] = startIndex;
            triangles[i + 10] = vertexCount + startIndex + 1;
            triangles[i + 11] = vertexCount + startIndex; 
            verticeIndex++;
        }
        startTriangleIndex = topTriangleCount * 2 * 3;

        // 前,后表面三角形,顶点索引
        verticeIndex = 0;
        for (int i = startTriangleIndex; i < startTriangleIndex + frontTriangleCount * 2 * 3 ; i += 12)
        {
            //前表面 ,第一条弧和第三条弧组成的面
            int startIndex = verticeIndex;
            int startVertexCount = vertexCount * 2; 
            // 顺时针, 第一个三角形
            triangles[i] = startIndex;
            triangles[i + 1] = startIndex + 1;
            triangles[i + 2] = startVertexCount + startIndex + 1; 
            // 顺时针, 第二个三角形
            triangles[i + 3] = startIndex;
            triangles[i + 4] = startVertexCount + startIndex + 1;
            triangles[i + 5] = startVertexCount + startIndex; 
            
            // 后表面, 第二条弧和第四条弧组成的面
            startIndex = verticeIndex + vertexCount;
            // 逆时针, 第一个三角形
            triangles[i + 6] = startIndex;
            triangles[i + 7] = startVertexCount + startIndex + 1; 
            triangles[i + 8] = startIndex + 1; 
            // 逆时针, 第二个三角形
            triangles[i + 9] = startIndex;
            triangles[i + 10] = startVertexCount + startIndex; 
            triangles[i + 11] = startVertexCount + startIndex + 1; 
            verticeIndex++;
        }
        startTriangleIndex += frontTriangleCount * 2 * 3;
        
        // 左,右 表面三角形,顶点索引
        verticeIndex = 0;
        for (int i = startTriangleIndex; i < startTriangleIndex + leftTriangleCount * 2 * 3 ; i += 12)
        {
            //左表面 ,四条弧的左端点组成的面
            int startIndex = verticeIndex;
            // 逆时针, 第一个三角形
            triangles[i] = startIndex;
            triangles[i + 1] = vertexCount * 3;  
            triangles[i + 2] = vertexCount;
            // 逆时针, 第二个三角形
            triangles[i + 3] = startIndex;
            triangles[i + 4] = vertexCount * 2; 
            triangles[i + 5] = vertexCount * 3; 
            
            // 右表面, 四条弧的右端点组成的面
            // 顺时针, 第一个三角形
            triangles[i + 6] = vertexCount - 1;
            triangles[i + 7] = vertexCount * 2 - 1; 
            triangles[i + 8] = vertexCount * 4 - 1;   
            // 顺时针, 第二个三角形
            triangles[i + 9] = vertexCount - 1;
            triangles[i + 10] = vertexCount * 4 - 1;  
            triangles[i + 11] = vertexCount * 3 - 1; 
            verticeIndex++;
        }

        //uv:
        // Vector2[] uvs = new Vector2[vertexCount * 2];
        // for (int i = 0; i < vertexCount; i++)
        // {
        //     uvs[i] = new Vector2(vertex[i].x / outerRadius / 2 + 0.5f, vertex[i].z / outerRadius / 2 + 0.5f);
        // }
        // for (int i = vertexCount; i < vertexCount * 2; i++)
        // {
        //     uvs[i] = new Vector2(vertex[i].x / innerRadius / 2 + 0.5f, vertex[i].z / innerRadius / 2 + 0.5f);
        // }

        //负载属性与mesh
        Mesh mesh = new Mesh();
        mesh.vertices = vertex;
        mesh.triangles = triangles;
        mesh.RecalculateNormals();
        // mesh.uv = uvs;
        return mesh;
    }
}

使用的shader两个,颜色+线框

颜色: 随便搞一个只要支持Color设置即可

线框:项目内搞的,后面补充一个公版引擎能用的。 如果急用,可自行百度或发邮件

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity3D 中绘制扇形检测需要使用以下步骤: 1. 创建一个扇形的 Mesh。 可以使用 Unity3D 的内置函数来创建扇形的 Mesh,例如: ```csharp // 创建一个半径为 1,角度为 90 度的扇形 Mesh Mesh CreateSectorMesh(float radius, float angle) { int segments = 16; // 分段数 float startAngle = -angle / 2; // 起始角度 float endAngle = angle / 2; // 终止角度 float deltaAngle = angle / segments; // 每个分段的角度差 Vector3[] vertices = new Vector3[segments + 2]; // 顶点数组 int[] triangles = new int[segments * 3]; // 三角形数组 // 中心点 vertices[0] = Vector3.zero; // 顶点 for (int i = 1; i <= segments + 1; i++) { float theta = Mathf.Deg2Rad * (startAngle + (i - 1) * deltaAngle); vertices[i] = new Vector3(radius * Mathf.Cos(theta), 0, radius * Mathf.Sin(theta)); } // 三角形 for (int i = 0; i < segments; i++) { triangles[i * 3] = 0; triangles[i * 3 + 1] = i + 1; triangles[i * 3 + 2] = i + 2; } Mesh mesh = new Mesh(); mesh.vertices = vertices; mesh.triangles = triangles; mesh.RecalculateNormals(); mesh.RecalculateBounds(); return mesh; } ``` 2. 创建一个扇形的 Collider。 可以使用 Unity3D 的内置函数来创建扇形的 Collider,例如: ```csharp // 创建一个半径为 1,角度为 90 度的扇形 Collider Collider CreateSectorCollider(float radius, float angle) { GameObject go = new GameObject(); MeshCollider collider = go.AddComponent<MeshCollider>(); Mesh mesh = CreateSectorMesh(radius, angle); // 创建扇形的 Mesh collider.sharedMesh = mesh; return collider; } ``` 3. 检测是否有物体在扇形区域内。 可以使用 Collider 的 OverlapSphere 和 OverlapSphereNonAlloc 函数来检测是否有物体在扇形区域内,例如: ```csharp // 检测是否有物体在扇形区域内,返回符合条件的物体列表 List<GameObject> CheckSectorOverlap(Vector3 center, float radius, float angle, LayerMask layerMask) { Collider collider = CreateSectorCollider(radius, angle); // 创建扇形的 Collider collider.transform.position = center; // 设置中心点 collider.transform.rotation = Quaternion.identity; // 设置旋转角度 Collider[] colliders = Physics.OverlapSphere(center, radius, layerMask); // 获取符合条件的碰撞体列表 List<GameObject> list = new List<GameObject>(); foreach (Collider c in colliders) { if (c.bounds.Intersects(collider.bounds)) // 判断是否在扇形区域内 { list.Add(c.gameObject); } } Destroy(collider.gameObject); // 销毁 Collider return list; } ``` 这样就可以在 Unity3D 中绘制扇形检测了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值