Unity 3D饼状图效果
2026/6/12 6:53:13 网站建设 项目流程

一. 效果展示

二.基础类

using System.Collections; using System.Collections.Generic; using UnityEngine; public class DrawCylinder : MonoBehaviour { // 网格渲染器 MeshRenderer meshRenderer; // 网格过滤器 MeshFilter meshFilter; // 用来存放顶点数据 List<Vector3> verts; // 顶点列表 List<int> indices; // 序号列表 private int count; private int height = 1; private Color color; private Texture tex; private Material material; private int Index; public static List<int> Counts = new List<int>(); public void Init(int _index, List<int> list,int _count, Texture texture) { verts = new List<Vector3>(); indices = new List<int>(); meshRenderer = GetComponent<MeshRenderer>(); meshFilter = GetComponent<MeshFilter>(); 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占的份额,总份额是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 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 } } }

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询