unity 做一个圆形分比图
// 在其他脚本中控制多段进度
using System.Collections.Generic;
using UnityEngine;public class GameManager : MonoBehaviour
{public MultiCircleProgress circleProgress;void Start(){// 初始化数据circleProgress.segments = new List<MultiCircleProgress.ProgressSegment>{new MultiCircleProgress.ProgressSegment{name = "",progress = 0.2f,color = Color.red},new MultiCircleProgress.ProgressSegment{name = "",progress = 0.3f,color = Color.blue},new MultiCircleProgress.ProgressSegment{name = "",progress = 0.3f,color = Color.green},new MultiCircleProgress.ProgressSegment{name = "",progress = 0.1f,color = Color.black},new MultiCircleProgress.ProgressSegment{name = "",progress = 0.1f,color = Color.cyan}};circleProgress.CreateSegments();}void UpdatePlayerStats(float health, float mana, float stamina){circleProgress.UpdateSegment(0, health);circleProgress.UpdateSegment(1, mana);circleProgress.UpdateSegment(2, stamina);}
}```
脚本挂到场景中一个模型上,脚本可以设置生成得比例```csharp
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;public class MultiCircleProgress : MonoBehaviour
{[System.Serializable]public class ProgressSegment{public string name;[Range(0, 1)] public float progress;public Color color;[HideInInspector] public Image fillImage;[HideInInspector] public Text textComponent;}[Header("UI Elements")]public List<ProgressSegment> segments = new List<ProgressSegment>();public GameObject segmentPrefab;public Text percentTextTemplate;public Transform textContainer;[Header("Text Positioning")]public float textDistanceFromCenter = 0.7f; // 基于半径的比例 (0.5=边缘, 1.0=两倍半径)public float textOffsetAngle = 0f;public float textMinDistance = 30f;public float textMaxDistance = 200f;private RectTransform baseRectTransform;private float baseRadius;void Start(){InitializeComponents();CreateSegments();}void InitializeComponents(){baseRectTransform = GetComponent<RectTransform>();baseRadius = Mathf.Min(baseRectTransform.rect.width, baseRectTransform.rect.height) / 2f;}public void CreateSegments(){ClearExistingSegments();ClearExistingTexts();float currentRotation = 0f;for (int i = 0; i < segments.Count; i++){CreateSegment(i, ref currentRotation);}}void ClearExistingSegments(){foreach (Transform child in transform){if (child != textContainer) Destroy(child.gameObject);}}void ClearExistingTexts(){if (textContainer != null){foreach (Transform child in textContainer){Destroy(child.gameObject);}}}void CreateSegment(int index, ref float currentRotation){// 创建进度段GameObject segmentObj = Instantiate(segmentPrefab, transform);segments[index].fillImage = segmentObj.GetComponent<Image>();// 配置段属性ConfigureSegment(index, currentRotation);// 创建并定位文本if (percentTextTemplate != null && textContainer != null){CreateSegmentText(index, currentRotation);}currentRotation += segments[index].progress * 360f;}void ConfigureSegment(int index, float rotation){segments[index].fillImage.color = segments[index].color;segments[index].fillImage.type = Image.Type.Filled;segments[index].fillImage.fillMethod = Image.FillMethod.Radial360;segments[index].fillImage.fillOrigin = (int)Image.Origin360.Top;segments[index].fillImage.fillClockwise = true;segments[index].fillImage.transform.rotation = Quaternion.Euler(0, 0, -rotation);segments[index].fillImage.fillAmount = segments[index].progress;}void CreateSegmentText(int index, float segmentStartRotation){Text textObj = Instantiate(percentTextTemplate, textContainer);textObj.gameObject.SetActive(true);segments[index].textComponent = textObj;textObj.text = $"{segments[index].name} {Mathf.RoundToInt(segments[index].progress * 100)}%";textObj.color = segments[index].color;PositionTextOutsideCircle(index, segmentStartRotation);}void PositionTextOutsideCircle(int index, float segmentStartRotation){if (segments[index].textComponent == null) return;// 计算当前半径float currentRadius = Mathf.Min(Mathf.Max(baseRectTransform.rect.width, baseRectTransform.rect.height) / 2f,textMaxDistance);// 计算有效文本距离 (基于比例但限制在最小/最大值之间)float effectiveTextDistance = Mathf.Max(currentRadius * textDistanceFromCenter,textMinDistance);// 计算扇形中心角度float midAngle = segmentStartRotation + (segments[index].progress * 180f) + textOffsetAngle;// 计算文本位置 (圆形中心向外延伸)Vector3 textDirection = Quaternion.Euler(0, 0, -midAngle) * Vector3.up;segments[index].textComponent.rectTransform.anchoredPosition = textDirection * effectiveTextDistance;// 保持文本水平segments[index].textComponent.rectTransform.localRotation = Quaternion.identity;// 设置文本锚点为中心,方便定位segments[index].textComponent.rectTransform.anchorMin =segments[index].textComponent.rectTransform.anchorMax =segments[index].textComponent.rectTransform.pivot = new Vector2(0.5f, 0.5f);}public void UpdateAllProgress(){float currentRotation = 0f;for (int i = 0; i < segments.Count; i++){segments[i].progress = Mathf.Clamp01(segments[i].progress);// 更新填充和旋转if (segments[i].fillImage != null){segments[i].fillImage.transform.rotation = Quaternion.Euler(0, 0, -currentRotation);segments[i].fillImage.fillAmount = segments[i].progress;}// 更新文本if (segments[i].textComponent != null){segments[i].textComponent.text = $"{segments[i].name}: {Mathf.RoundToInt(segments[i].progress * 100)}%";PositionTextOutsideCircle(i, currentRotation);}currentRotation += segments[i].progress * 360f;}}public void UpdateSegment(int index, float progress){if (index >= 0 && index < segments.Count){segments[index].progress = Mathf.Clamp01(progress);UpdateAllProgress();}}#if UNITY_EDITORvoid OnValidate(){if (baseRectTransform == null)baseRectTransform = GetComponent<RectTransform>();if (!Application.isPlaying && baseRectTransform != null){UnityEditor.EditorApplication.delayCall += () => {if (this != null) UpdateAllProgress();};}}
#endif
}
创建UI结构:
创建 Canvas
在 Canvas 下创建空对象 “MultiProgress”
创建空对象 “TextContainer” 作为文本父对象
准备预制体:
创建 Image 对象,命名为 “SegmentPrefab”
设置为 Filled 类型,Fill Method 为 Radial 360
将其做成预制体
准备文本模板:
创建 Text 对象,设置好字体样式
初始设置为非激活状态
命名为 “PercentTextTemplate”
添加组件:
给 “MultiProgress” 对象添加 MultiCircleProgress 脚本
将预制体和文本模板拖拽到脚本对应字段
在 Inspector 中添加和配置各个段
相关文章:
unity 做一个圆形分比图
// 在其他脚本中控制多段进度 using System.Collections.Generic; using UnityEngine;public class GameManager : MonoBehaviour {public MultiCircleProgress circleProgress;void Start(){// 初始化数据circleProgress.segments new List<MultiCircleProgress.ProgressS…...
JAVA反序列化深入学习(八):CommonsCollections6
与CC5相似: 在 CC5 中使用了 TiedMapEntry#toString 来触发 LazyMap#get在 CC6 中是通过 TiedMapEntry#hashCode 来触发 LazyMap#get 之前看到了 hashcode 方法也会调用 getValue() 方法然后调用到其中 map 的 get 方法触发 LazyMap,那重点就在于如何在反…...
鸿蒙项目源码-外卖点餐-原创!原创!原创!
鸿蒙外卖点餐外卖平台项目源码含文档包运行成功ArkTS语言。 我半个月写的原创作品,请尊重原创。 原创作品,盗版必究!!! 原创作品,盗版必究!!! 原创作品,盗版…...
计算机二级WPS Office第十一套WPS演示
解题过程...
React程序打包与部署
===================== 推荐超级课程: 本地离线DeepSeek AI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战目录 为生产环境准备React应用最小化和打包环境变量错误处理部署到托管服务部署到Netlify探索高级主题:Hooks、Su…...
ubuntu 创建新用户
给实验室服务器建用户,会担心除了基本的用户创建以外有没有别的没考虑到的。问了一下似乎没有,就按最基础的来就可以 # linux 自带的基础命令 # 创建用户,指定 home,设置 owner,设置密码 sudo useradd -d /home/abc a…...
代码随想录刷题day53|(二叉树篇)106.从中序与后序遍历序列构造二叉树(▲
目录 一、二叉树理论知识 二、构造二叉树思路 2.1 构造二叉树流程(给定中序后序 2.2 整体步骤 2.3 递归思路 2.4 给定前序和后序 三、相关算法题目 四、易错点 一、二叉树理论知识 详见:代码随想录刷题day34|(二叉树篇)二…...
Leetcode算法方法总结
1. 双指针法解决链表/数组题目 只要数组有序,就要想到双指针做法。还有二分法 回文串一般也会用到双指针,回文串的长度由于可能是奇数也可能是偶数,所以在寻找时,既需要寻找奇数长度的回文串,也需要寻找偶数长度的回文…...
全包圆玛奇朵样板间亮相,极简咖啡风引领家装新潮流
在追求品质生活的当下,家居装修风格的选择成为了许多消费者关注的焦点。近日,全包圆家居装饰有限公司精心打造的玛奇朵样板间正式对外开放,以其独特的咖啡色系极简风格,为家装市场带来了一股清新的潮流。玛奇朵样板间不仅展示了全…...
小红书多账号运营:如何实现每个账号独立 IP发布文章
一、多账号管理与 IP 隔离方案 1.电脑端实现:推荐使用指纹浏览器工具,为每个账号生成独立设备指纹(模拟不同 MAC 地址、内存等信息),并搭配兔子ip代理等服务商的 SOCKS5 代理,实现一机多开且每个账号独立 …...
大数据学习(92)-spark详解
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言📝支持一…...
免费下载 | 2025年网络安全报告
报告总结了2024年的网络安全态势,并对2025年的安全趋势进行了预测和分析。报告涵盖了勒索软件、信息窃取软件、云安全、物联网设备安全等多个领域的安全事件和趋势,并提供了安全建议和最佳实践。 一、报告背景与目的 主题:2024企业信息安全峰…...
《Android低内存设备性能优化实战:深度解析Dalvik虚拟机参数调优》
1. 痛点分析:低内存设备的性能困局 现象描述:大应用运行时频繁GC导致卡顿 根本原因:Dalvik默认内存参数与硬件资源不匹配 解决方向:动态调整堆内存参数以平衡性能与资源消耗 2. 核心调优参数全景解析 关键参数矩阵࿱…...
RCE--解法
目录 一、利用php伪协议 1.代码分析 2.过程 3.结果 编辑 4.防御手段 二、RCE(php中点的构造) 1.代码分析 2.过程 一、利用php伪协议 <?php error_reporting(0); if(isset($_GET[c])){$c $_GET[c];if(!preg_match("/flag|system|php|cat|sort…...
JAVA反序列化深入学习(九):CommonsCollections7与CC链总结
CC7 依旧是寻找 LazyMap 的触发点 CC6使用了 HashSet而CC6使用了 Hashtable JAVA环境 java version "1.8.0_74" Java(TM) SE Runtime Environment (build 1.8.0_74-b02) Java HotSpot(TM) 64-Bit Server VM (build 25.74-b02, mixed mode) 依赖版本 Apache Commons …...
HTML元素小卖部:表单元素 vs 表格元素选购指南
刚学HTML的同学经常把表单和表格搞混,其实它们就像超市里的食品区和日用品区——虽然都在同一个超市,但用途完全不同。今天带你3分钟分清这两大元素家族! 一、表单元素家族(食品区:收集用户输入) 1. <i…...
如何使用 Bash 脚本自动化清理 Nacos 日志文件
如何使用 Bash 脚本自动化清理 Nacos 日志文件 在现代的分布式系统中,Nacos 作为服务发现、配置管理和动态服务管理的核心组件,其日志文件的管理显得尤为重要。随着系统的运行,日志文件会不断累积,占用大量磁盘空间。如果不及时清理,可能会导致磁盘空间不足,影响系统性能…...
群体智能优化算法-算术优化算法(Arithmetic Optimization Algorithm, AOA,含Matlab源代码)
摘要 算术优化算法(Arithmetic Optimization Algorithm, AOA)是一种新颖的群体智能优化算法,灵感来源于加、减、乘、除四种基本算术运算。在优化过程中,AOA 通过乘除操作实现全局探索,通过加减操作强化局部开发&#…...
Redis6数据结构之String类型
redis的String类型是存储字符串类型的key-value。 应用场景:验证码、计数器(包括点赞数、文章/视频浏览数)、订单重复提交、用户登录信息、商品详情。 常用命令: set/get设置和获取key-valuemset/mget批量设置或获取多个key的…...
uniapp中的流式输出
一、完整代码展示 目前大多数的ai对话都是流式输出,也就是对话是一个字或者多个字逐一进行显示的下面是一个完整的流式显示程序,包含的用户的消息发出和ai的消息回复 <template><view class"chat-container"><view class&quo…...
理解 C++ 中的顶层 const 与底层 const(二十四)
1. 示例解析 下面的代码展示了不同 const 限定符的组合及其含义: int i 0; int *const p1 &i; // p1 是一个常量指针:p1 本身不可改变(顶层 const),但 *p1 所指的 int 可修改 const int ci 42; …...
Linux之数据链路层
Linux之数据链路层 一.以太网1.1以太网帧格式1.2MAC地址1.3MTU 二.ARP协议2.1ARP协议工作流程2.2ARP协议格式 三.NAT技术四.代理服务4.1正向代理4.2反向代理 五.四大层的学习总结 一.以太网 在我们学习完了网络层后我们接下来就要进入数据链路层的学习了,在学习完网…...
如何在 vue 渲染百万行数据,vxe-table 渲染百万行数据性能对比,超大量百万级表格渲染
vxe-table 渲染百万行数据性能对比,超大量百万级表格渲染;如何在 vue 渲染百万行数据;当在开发项目时,遇到需要流畅支持百万级数据的表格时, vxe-table 就可以非常合适了,不仅支持强大的功能,虚…...
std::reference_wrapper 和 std::function的详细介绍
关于 std::reference_wrapper 和 std::function 的详细介绍及具体测试用例: 1. std::reference_wrapper(引用包装器) 核心功能 包装引用:将引用转换为可拷贝、可赋值的对象支持隐式转换:可自动转换为原始引用类型容器…...
如何封装一个上传文件组件
#今天用el-upload感到很多不方便,遂决定自己封装一个。注:本文不提供表面的按钮样式和文件上传成功后的样式,需要自己创建。本文仅介绍逻辑函数# 1,准备几个表面用来指引上传的元素 2,创造统一的隐藏文件上传输入框&…...
MySQL-5.7.37安装配置(Windows)
1.下载MySQL-5.7.37软件包并解压 2.配置本地环境变量 打开任务栏 搜索高级系统设置 新建MySQL的环境变量 然后在path中添加%MYSQL_HOME%\bin 3.在MySQL-5.7.37解压的文件夹下新建my.ini文件并输入以下内容 [mysqld]#端口号port 3306#mysql-5.7.27-winx64的路径basedirC:\mysq…...
CentOS与Ubuntu命令对比指南:从软件包管理到系统配置
CentOS与Ubuntu命令对比指南 作为两大主流Linux发行版,**CentOS(基于RHEL)和Ubuntu(基于Debian)**在日常运维中常因命令差异引发混淆。本文通过关键场景对比,助您快速掌握两者的核心操作区别。 一、软件包管理:yum/dnf vs apt 操作CentOSUbuntu更新软件源yum check-upd…...
鸿蒙北向应用开发:deveco 5.0 kit化文件相关2
鸿蒙北向应用开发:deveco 5.0 kit化文件相关 在kit化时,有时候会出现这样一种场景即你想把已有的d.ts导出换个名字,这样从名字上更贴合你的kit聚合 什么意思呢?比如现在有 ohos.hilog.d.ts 导出了hilog,现在你想kit化hilog,使得hilog导出名字为usrhilog,这样用户在使用你的k…...
《HelloGitHub》第 108 期
兴趣是最好的老师,HelloGitHub 让你对开源感兴趣! 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 github.com/521xueweihan/HelloGitHub 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等,涵盖多种编程语言 Python、…...
C++可变参数
可变参数C风格的可变参数C风格可变参数的使用 C11可变参数模板递归展开参数包参数列表展开折叠表达式 STL中的emplace插入接口 可变参数 C风格的可变参数 可变参数是一种语言特性,可以在函数声明中使用省略号...来表示函数接受可变数量的参数。 例如典型的printf…...
