Unity 3D饼状图效果

Unity 3D饼状图效果 一. 效果展示二.基础类using System.Collections; using System.Collections.Generic; using UnityEngine; public class DrawCylinder : MonoBehaviour { // 网格渲染器 MeshRenderer meshRenderer; // 网格过滤器 MeshFilter meshFilter; // 用来存放顶点数据 ListVector3 verts; // 顶点列表 Listint indices; // 序号列表 private int count; private int height 1; private Color color; private Texture tex; private Material material; private int Index; public static Listint Counts new Listint(); public void Init(int _index, Listint list,int _count, Texture texture) { verts new ListVector3(); indices new Listint(); meshRenderer GetComponentMeshRenderer(); meshFilter GetComponentMeshFilter(); material meshRenderer.material; Index _index; Counts list; count _count; if (Counts.Count 0) { return; } tex texture; verts.Clear(); indices.Clear(); Generate(); material.SetTexture(_MainTex, tex); } public void Generate() { float avgAngle 1; Vector3 twoVert new Vector3(1f, 0, 0); float angle 0; for (int i 0; i count; i) { 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), -height, -Mathf.Sin(angle * Mathf.Deg2Rad))); 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(Vector3.zero); verts.Add(new Vector3(0, -height, 0)); 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设置部分添加 Vector2[] uvs new Vector2[verts.Count]; for (int i 0; i verts.Count; i) { uvs[i] new Vector2( verts[i].x, verts[i].z ); } mesh.uv uvs; 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占的份额总份额是360index是索引。注意子节点上面显示的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 { RenderTypeOpaque } Cull Off Pass { 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 } } }