Bootstrap

【第009问 Unity如何通过Triangle、Mesh画圆?】

视频讲解

Unity中通过Triangles、Mesh画圆

绘制圆的方式很多,本文只是针对Triangle、Mesh、SubMesh的实践;尤其是内容中SubMesh的问题,建议个人更改里面的参数进行测试掌握相关知识点。

一、动画演示

在这里插入图片描述

二、源码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ValakiMeshCircleDemos : MonoBehaviour
{
    MeshFilter meshFilter;


    [SerializeField] List<Material> materials;

    [SerializeField] int totalTriangles = 5;
    [SerializeField] float speed = 0.25f;
    [SerializeField] bool isLoop = false;

    int radius = 1;

    [SerializeField] int maxTriangles = 100;
    [SerializeField] int minTriangles = 3;

    WaitForSeconds waitForSeconds;

    private void Awake()
    {
        meshFilter = GetComponent<MeshFilter>();
        waitForSeconds = new WaitForSeconds(speed);
    }


    // Start is called before the first frame update
    void Start()
    {

        if (isLoop)
            StartCoroutine(AddTriangleToCircle());
        else
            CreateCircle();
    }


    /// <summary>
    /// 给圆加三角形
    /// </summary>
    /// <returns></returns>
    IEnumerator AddTriangleToCircle()
    {
        yield return waitForSeconds;
        totalTriangles++;
        CreateCircle();
        if (totalTriangles < maxTriangles)
            StartCoroutine(AddTriangleToCircle());
        else
            StartCoroutine(ReduceTriangleToCircle());
    }

    /// <summary>
    /// 给圆减少三角形 
    /// </summary>
    /// <returns></returns>
    IEnumerator ReduceTriangleToCircle()
    {
        yield return waitForSeconds;
        totalTriangles--;
        CreateCircle();
        if (totalTriangles <= minTriangles)
            StartCoroutine(AddTriangleToCircle());
        else
            StartCoroutine(ReduceTriangleToCircle());
    }

    void CreateCircle()
    {
        ReadyBaseData();
        DrawDetailCircle();

    }

    /// <summary>
    /// 准备基本数据
    /// </summary>
    void ReadyBaseData()
    {
        List<Material> _materials = new List<Material>();
        for (int i = 0; i < totalTriangles; i++)
        {
            int randomIndex = i % materials.Count;
            _materials.Add(materials[randomIndex]); 
        }
        //_materials.Add(materials[materials.Count - 1]);
        GetComponent<MeshRenderer>().materials = _materials.ToArray();
    }

    /// <summary>
    /// 实际绘制圆
    /// </summary>
    void DrawDetailCircle()
    {
        float singleAngel = -360.0f / totalTriangles;

        List<Vector3> vertices = new List<Vector3>();
        vertices.Add(Vector3.zero);
        Vector3 v2 = new Vector3(radius, 0, 0);
        vertices.Add(v2);

        for (int i = 1; i <= totalTriangles; i++)
        {
            float angel = singleAngel * i * Mathf.Deg2Rad;
            Vector3 v = new Vector3(Mathf.Cos(angel) / radius, Mathf.Sin(angel) / radius, 0);
            vertices.Add(v);
        }


        Mesh mesh = new Mesh();
        mesh.SetVertices(vertices.ToArray());

        mesh.subMeshCount = totalTriangles;
        List<int> indices = new List<int>() { 0, 1, 2 };
        for (int i = 0; i < totalTriangles; i++)
        {
            indices.Add(0);
            indices.Add(i + 1);
            indices.Add(i + 2);

            List<int> _indices = new List<int>() { 0, i + 1, i + 2 };
            mesh.SetIndices(_indices, MeshTopology.Triangles, i);
        }

        meshFilter.mesh = mesh;
    } 

} 

结语:
理想和实践之间总是存在一到鸿沟【valaki】