一. 效果展示
二.基础类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class DrawCylinder : MonoBehaviour
{// 网格渲染器MeshRenderer meshRenderer;// 网格过滤器MeshFilter meshFilter;// 用来存放顶点数据List<Vector3> verts; // 顶点列表List<int> indices; // 序号列表public int count = 270;private int preCount;private int height = 1;private Color preColor;public Color color = Color.blue;private Material material;public int Index;public static List<int> Counts = new List<int>() { 180,90,11,36,43};private void Start(){Debug.Log("DrawCylinder count " + count);verts = new List<Vector3>();indices = new List<int>();meshRenderer = GetComponent<MeshRenderer>();meshFilter = GetComponent<MeshFilter>();material = meshRenderer.material;Generate();}private void Update(){if (preCount != count) {preCount = count;verts.Clear();indices.Clear();Generate();}if (preColor != color) {preColor = color;material.SetColor("_Color", color);}}public void Generate(){int avgAngle = 1;Vector3 twoVert = new Vector3(1, 0, 0);for (int i = 0; i < count; i++){int angle = avgAngle * (i + 1);verts.Add(Vector3.zero);verts.Add(twoVert);verts.Add(new Vector3(Mathf.Cos(angle * Mathf.Deg2Rad), 0, -Mathf.Sin(angle * Mathf.Deg2Rad)));verts.Add(new Vector3(0, -height, 0));verts.Add(twoVert + new Vector3(0, -height, 0));verts.Add(new Vector3(Mathf.Cos(angle * Mathf.Deg2Rad), -height, -Mathf.Sin(angle * Mathf.Deg2Rad)));verts.Add(twoVert);verts.Add(twoVert + new Vector3(0, -height, 0));verts.Add(Vector3.zero);verts.Add(twoVert + new Vector3(0, -height, 0));verts.Add(new Vector3(0, -height, 0));verts.Add(Vector3.zero);verts.Add(Vector3.zero);verts.Add(new Vector3(Mathf.Cos(angle * Mathf.Deg2Rad), 0, -Mathf.Sin(angle * Mathf.Deg2Rad)));verts.Add(new Vector3(Mathf.Cos(angle * Mathf.Deg2Rad), -height, -Mathf.Sin(angle * Mathf.Deg2Rad)));verts.Add(new Vector3(Mathf.Cos(angle * Mathf.Deg2Rad), -height, -Mathf.Sin(angle * Mathf.Deg2Rad)));verts.Add(new Vector3(0, -height, 0));verts.Add(Vector3.zero);verts.Add(twoVert);verts.Add(twoVert + new Vector3(0, -height, 0));verts.Add(new Vector3(Mathf.Cos(angle * Mathf.Deg2Rad), 0, -Mathf.Sin(angle * Mathf.Deg2Rad)));verts.Add(twoVert + new Vector3(0, -height, 0));verts.Add(new Vector3(Mathf.Cos(angle * Mathf.Deg2Rad), -height, -Mathf.Sin(angle * Mathf.Deg2Rad)));verts.Add(new Vector3(Mathf.Cos(angle * Mathf.Deg2Rad), 0, -Mathf.Sin(angle * Mathf.Deg2Rad)));for (int j = i * 24; j < 24 * (i + 1); j++){indices.Add(j);}twoVert = new Vector3(Mathf.Cos(angle * Mathf.Deg2Rad), 0, -Mathf.Sin(angle * Mathf.Deg2Rad));}Mesh mesh = new Mesh();mesh.SetVertices(verts);mesh.SetIndices(indices, MeshTopology.Triangles, 0);// 自动计算法线mesh.RecalculateNormals();// 自动计算物体的整体边界mesh.RecalculateBounds();// 将mesh对象赋值给网格过滤器,就完成了meshFilter.mesh = mesh;//设置角度int c = 0;for (int i = 0; i < Counts.Count; i++){if (i > Index){break;}c += Counts[i];transform.localEulerAngles = new Vector3(0, -c, 0);}//设置位置int max = 0;for (int i = 0; i < Counts.Count; i++){if (Counts[i] > max){max = Counts[i];}}if (max == count){transform.localScale = new Vector3(1, 1, 1);transform.localPosition = Vector3.zero;}else {float h = count * 1f / max;transform.localScale = new Vector3(1, h, 1);transform.localPosition = new Vector3(0, -(height - h), 0);}}
}
三.UI目录
四. 子节点上添加MeshRender和MeshFilter组件, 把DrawCylinder脚本挂在每个子节点上,调整参数,count占的份额,总份额是360,index是索引。注意,子节点上面显示的count和index,需要和DrawCylinder类里面的Counts列表索引和数额对应一样。
五.给子节点换上Cull Off 的材质,新建材质球,把shader拖到材质球上,再把材质球给到每个子节点,shader代码如下
Shader "Unlit/DrawCylinderShader"
{Properties{_Color ("Color", Color) = (0,0,0,0)_Diffuse("Diffuse", Color) = (1,1,1,1)_Value("Diffuse", float) = 1}SubShader{Tags { "RenderType"="Opaque" }Cull OffPass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "Lighting.cginc"#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;float3 normal:NORMAL;};fixed4 _Color;uniform fixed4 _Diffuse;float _Value;struct v2f{float2 uv : TEXCOORD0;float3 worldNormal:TEXCOORD1;float4 vertex : SV_POSITION;};v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);return o;}fixed4 frag (v2f i) : SV_Target{fixed3 worldNormal = normalize(i.worldNormal);fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);fixed3 lambert = saturate(dot(worldNormal, worldLightDir));fixed3 albedo = (lambert * _Diffuse.xyz * _LightColor0.xyz + UNITY_LIGHTMODEL_AMBIENT.xyz) * _Value;return fixed4(_Color.xyz * albedo,1) ;}ENDCG}}
}