FairyGUI 实现 Boss 双层血条动画
涉及到一个问题的话先去了解前因后果,涉及到的UI框架,全部吃懂吃透。
一:理解血条系统的组成
1.boss血条一般包括:
红色血条:表示当前血量,随伤害立即减少;
白色血条(残影):慢慢减少,产生一种“缓冲”的受伤视觉效果;
血条分段(如 2 条血表示不同阶段);
血条消失/出现动画;
血条附加信息:如 Boss 名字、阶段数、状态效果等。
二: 准备环境
Unity + FairyGUI
准备血条 UI 元素:
使用两张图层叠加实现红色与白色残影效果。
可以用
GProgressBar
或者GImage
手动设置宽度控制进度。数据结构设计:
定义 Boss 最大血量
maxHp
当前血量
currentHp
白色缓冲血量
whiteHp
(用于残影效果)立即更新 Boss 血条,通常在第一次显示或需要立即更新时调用:
从事件参数中获取当前血量和最大血量
计算每条血条代表的血量值
计算当前填充的血条数和部分填充比例
使用 TweenValue 实现血条变化的动画效果
更新阶段文本
调用 UpdateBossHpWithEffect 实现后续动画效果
带延迟动画效果的血量更新,处理更复杂的动画效果:
计算血条分段和填充比例
处理跨阶段变化的特殊动画效果:
如果血条阶段减少(如从 2 阶段到 1 阶段)
先快速清空白条
然后使用定时器延迟执行后续动画
同阶段内变化则直接缓慢更新白条
三:血条动画
红条(RedBar)
用于立即体现 Boss 受伤
执行
.TweenValue(…)
,时间短(0.1s)白条(WhiteBar)
用于体现“血量丢失动画”
在延迟 0.6 秒后再
.TweenValue()
补位通过定时器分两次动画模拟先抖动再平滑拉回
类似于下面这种血条:
红色血条:快速变化(0.1 秒),立即反映当前血量
白色血条:缓慢变化(0.8 秒),跟随红色血条但有延迟
阶段转换特效:
当血条阶段减少时(如从 2 阶段到 1 阶段)
先快速清空白条(0.2 秒)
延迟 0.3 秒后快速填充白条(0.2 秒)
再延迟 0.6 秒后缓慢设置到目标值(0.8 秒)
下面是大概的流程图:
总体框架:MVC架构 + FairyGUI +事件系统来构建Boss血条组件
组件角色 脚本 作用 控制器(逻辑) BossHpChangeCtrl.cs
监听事件,控制何时显示、隐藏、更新血条 视图(UI显示) BossHpChangeView.cs
操作 FairyGUI 元素,实现具体 UI 效果 数据来源 PlayerEvt
、Player
从玩家/怪物对象中获取属性,如 HP、霸体等
2.小血条与霸体条
霸体条
(BossbatiBar
)单独绑定事件BossBatiChange
,从角色属性中计算百分比进度。3.血条阶段计算逻辑
int currentHp; // 当前血量值 int maxHp; // 最大血量值 int m_BossHpNum; // 血条分段数(默认为2)// 计算得到的临时值 float hpPerBar = (float)maxHp / m_BossHpNum; // 每条血条代表的血量 float totalHpBars = currentHp / hpPerBar; // 当前占用的血条数(含小数) int filledBars = (int)totalHpBars; // 完整填充的整数血条数 float partialBarRatio = totalHpBars - filledBars; // 当前血条的填充比例(0-1)
该逻辑将当前血量转为 血条数量 + 当前血条进度。
支持非整除(比如血量 3500,3 条血条,每条 1000 时,会有
X3 50%
效果)。
4.延迟白条处理机制if (filledBars < lastFilledBars) {bossHpBarWhite.TweenValue(0, 0.2f);// 添加单次定时器(延迟0.3秒执行)testAniTimer1 = TimerMgr.Inst.AddTimerOnce(0.3f, () => {bossHpBarWhite.TweenValue(100, 0.2f);});// 添加单次定时器(延迟0.6秒执行)testAniTimer2 = TimerMgr.Inst.AddTimerOnce(0.6f, () => {bossHpBarWhite.TweenValue(partialBarRatio, 0.8f);}); }
红条立即变化
白条先归零,再慢慢追上,模拟视觉残留
用
TimerMgr
实现延迟回调逻辑,提升打击表现力5.Boss头像动态显示
var gloader = bossHpComponent.GetChild("n6").asLoader.component.GetChild("n5").asLoader; gloader.url = _url;
头像绑定在指定路径下,通过 URL 加载头像图片。
动态根据角色 ID 从配置中取出头像路径。
7.注意事项
定时器管理很重要,避免页面关闭后回调仍在执行
血条分段数
m_BossHpNum
应根据实际游戏设计调整动画时长参数可根据需求调整以获得最佳视觉效果
当前实现中隐藏了小血条(
miniHpLoader.visible = false
),如需使用需要取消隐藏动画分层:红色血条(快速)和白色血条(慢速)的分层设计,增强视觉效果
阶段检测:通过比较
lastTotalHpBars
和当前值,检测是否跨阶段资源清理:
RemoveTimer()
确保视图关闭时清理所有定时器
下面是树形结构
BossHpChangeView (BaseView)
└── m_Panel (GComponent)
└── (主容器 GComponent)
├── (红色血条背景 GLoader)
│ ├── (白色血条 GProgressBar)
│ └── (红色血条 GProgressBar)
├── (小血条 GLoader)
│ └── (小血条填充 GProgressBar)
├── (霸体条 GLoader)
│ └── (霸体进度条 GProgressBar)
├── (描述文本 GTextField)
└── (头像容器 GComponent)
└── (头像 GLoader)
事件和委托
1 事件参数结构 (BaseEvent/PlayerEvt)public class BaseEvent {// 基础事件类,可能包含事件类型等基础信息 }public class PlayerEvt : BaseEvent {public Player m_Value; // 包含玩家数据 }public class Player {// 玩家类,包含角色属性public int GetProperty(RoleProperty property){// 获取角色属性(血量、霸体值等)}public int m_RoleId; // 角色ID }
方法内部从事件参数提取玩家数据:
var evt = obj as PlayerEvt; var player = evt.m_Value; currentHp = (int)player.GetProperty(RoleProperty.Hp); maxHp = (int)player.GetProperty(RoleProperty.MaxHp);
四:性能优化实践
1.事件管理优化
void Show() {EventMgr.Inst.Register(EventId.BossHpChange, OnBossHpChange);// 其他事件注册... }void UnShow() {EventMgr.Inst.UnRegister(EventId.BossHpChange, OnBossHpChange);// 对称取消注册... }
事件驱动最佳实践
保持事件处理函数轻量
严格对称注册/反注册
使用强类型事件参数
2.动画定时器管理
void RemoveTimer() {if (testAniTimer1 != -1) TimerMgr.Inst.RemoveTimer(testAniTimer1);if (testAniTimer2 != -1) TimerMgr.Inst.RemoveTimer(testAniTimer2); }
3.血条更新算法:void UpdateBossHpImmediate(BaseEvent obj) {// 1. 计算血条分段float hpPerBar = (float)maxHp / m_BossHpNum;float totalHpBars = currentHp / hpPerBar;// 2. 应用动画效果bossHpBarRed.TweenValue(partialBarRatio * 100, 0.1f); // 红色快速变化bossHpBarWhite.TweenValue(partialBarRatio * 100, 0.8f);// 白色缓慢跟随// 3. 更新阶段文本hpBarPhaseLabel.text = filledBars > 1 ? $"X{filledBars}" : ""; }
4.跨阶段动画算法
void UpdateBossHpWithEffect() {// 检测阶段变化if (filledBars < lastFilledBars) {// 阶段减少特效bossHpBarWhite.TweenValue(0, 0.2f); // 快速清空TimerMgr.Inst.AddTimerOnce(0.3f, () => {bossHpBarWhite.TweenValue(100, 0.2f); // 快速填充});TimerMgr.Inst.AddTimerOnce(0.6f, () => {bossHpBarWhite.TweenValue(partialBarRatio, 0.8f); // 最终定位});} }
5.血条动画采用分层设计:
红色血条:线性变化,duration=0.1s(即时反馈)
白色血条:
常规变化:duration=0.8s(平滑跟随)
阶段变化:三段式动画(清空→全满→定位)