当前位置: 首页 > article >正文

Unity 3D饼状图效果

一. 效果展示

二.基础类

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 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
        }
    }
}


http://www.kler.cn/a/447114.html

相关文章:

  • 31.设计模式
  • 【Leecode】Leecode刷题之路第87天之扰乱字符串
  • 【线性代数】理解矩阵乘法的意义(点乘)
  • Qt同步读取串口
  • 手眼标定工具操作文档
  • excel 使用vlook up找出两列中不同的内容
  • 深度学习实战101-基于生成对抗网络GAN在医学核磁共振跨模态的应用,以及性能优化,并结合代码实例进行说明
  • Pytorch | 从零构建Vgg对CIFAR10进行分类
  • 安全算法基础(一)
  • 【Prompt Engineering】7 聊天机器人
  • nginx-rtmp服务器搭建
  • 理解torch函数squeeze和unsqueeze
  • 金融保险行业数字化创新实践:如何高效落地自主可控的企业级大数据平台
  • Midjourney各类型咒语汇总
  • 千亿级市场新机遇,品牌如何紧跟“宠”爱趋势创新宠物营销?
  • Redis 常用配置项说明
  • 学习go中的Resty, 比标准库net/http更加方便友好
  • 最大转矩电流比(MTPA)
  • uniapp入门 01创建项目模版
  • 融合注意力机制的卷积神经网络-双向长短期记忆网络(CNN-BiLSTM-Attention)的多变量/时间序列预测/matlab代码
  • C:\Windows 文件夹
  • 大模型微调---Lora微调实战
  • jsp中的四个域对象(Spring MVC)
  • 浅谈目前我开发的前端项目用到的设计模式
  • 爬取Q房二手房房源信息
  • Partition Strategies kafka分区策略