Unity中实现多层血条
Posted Hello Bug.
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity中实现多层血条相关的知识,希望对你有一定的参考价值。
一:效果演示
二:使用
——面板参数设置
HpSlider:Slider组件
TopBar:顶部血条
DownBar:底部血条
LastBarColor:最后一条血条的颜色
T:血量改变时缓动的插值(如果不需要缓动效果则设置为1即可)
——常规使用
创建Slider组件,添加HpBar脚本
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour
public HpBar hpBar;
private void Awake()
List<Color> colorList = new List<Color>() Color.blue, Color.cyan, Color.green, Color.red ;
hpBar.SetHpBar(100, colorList);
private void Update()
if (Input.GetKeyDown(KeyCode.A))
hpBar.ChangeValue(6);
if (Input.GetKeyDown(KeyCode.D))
hpBar.ChangeValue(-8);
——其他使用
CurIndex:当前第几管血
CurHp:当前血量
OnValueChanged:每次血量改变时的回调
OnIndexChanged:每次血条下标改变时的回调
三:代码实现
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;
/// <summary>
/// 血条
/// </summary>
public class HpBar : MonoBehaviour
//血条slider组件
public Slider hpSlider;
//顶部血条
public Image topBar;
//底部血条
public Image downBar;
//最后一个血条颜色
public Color lastBarColor;
//缓动差值
public float t = 0.1f;
//血条数值变化后
public Action<int, long> OnValueChanged;
//血条下标变化后
public Action<int, long> OnIndexChanged;
//当前下标(第几管血,降序)
int m_CurIndex;
public int CurIndex
get
return m_CurIndex;
//当前血量
long m_CurHp;
public long CurHp
get
return m_CurHp;
//总血量
long m_TotalHp;
//每一管血条的血量
float m_PerValue;
//血条颜色列表
List<Color> m_ColorList = new List<Color>();
//目标值
float m_TargetValue;
//目标下标
int m_TargetIndex;
/// <summary>
/// 设置血条
/// </summary>
public void SetHpBar(long totalHp, List<Color> colorList, long curHp = -1)
m_ColorList.Clear();
m_TotalHp = totalHp;
m_ColorList = colorList;
m_CurHp = curHp == -1
? m_TotalHp
: curHp;
InitHpBar();
/// <summary>
/// 设置血条
/// </summary>
public void SetHpBar(long totalHp, List<string> colorList, long curHp = -1)
m_ColorList.Clear();
m_TotalHp = totalHp;
foreach (var colorhtml in colorList)
Color color;
ColorUtility.TryParseHtmlString(colorHtml, out color);
m_ColorList.Add(color);
m_CurHp = curHp == -1
? m_TotalHp
: curHp;
InitHpBar();
/// <summary>
/// 初始化血条
/// </summary>
void InitHpBar()
m_PerValue = m_TotalHp * 1f / m_ColorList.Count;
hpSlider.minValue = 0;
hpSlider.maxValue = m_PerValue;
UpdateIndexAndValue();
UpdateHpBar(true);
UpdateColor();
/// <summary>
/// 更新血条颜色
/// </summary>
void UpdateColor()
topBar.color = m_ColorList[m_CurIndex - 1];
downBar.color = m_CurIndex - 1 <= 0
? lastBarColor
: m_ColorList[m_CurIndex - 2];
/// <summary>
/// 更新目标下标和目标值
/// </summary>
void UpdateIndexAndValue()
//更新下标
int targetIndex = 1;
int indexOffset = m_CurHp % m_PerValue <= 0.01f
? Mathf.FloorToInt(m_CurHp / m_PerValue) - 1
: Mathf.FloorToInt(m_CurHp / m_PerValue);
targetIndex = Mathf.Clamp(targetIndex + indexOffset, 1, m_ColorList.Count);
m_TargetIndex = targetIndex;
//更新值
float targetValue = 0;
if (m_CurHp % m_PerValue <= 0.01f)
if (m_TargetIndex == 1
&& m_CurHp != m_PerValue)
targetValue = 0;
else
targetValue = m_PerValue;
else
targetValue = m_CurHp % m_PerValue;
m_TargetValue = targetValue;
OnValueChanged?.Invoke(m_CurIndex, m_CurHp);
/// <summary>
/// 更新血条
/// </summary>
void UpdateHpBar(bool isForce)
if (isForce)
m_CurIndex = m_TargetIndex;
hpSlider.value = m_TargetValue;
OnValueChanged?.Invoke(m_CurIndex, m_CurHp);
else
if (m_CurIndex == m_TargetIndex)
hpSlider.value = Mathf.Lerp(hpSlider.value, m_TargetValue, t);
if (Mathf.Abs(hpSlider.value - m_TargetValue) <= 0.01f)
hpSlider.value = m_TargetValue;
else
if (m_CurIndex < m_TargetIndex)
hpSlider.value = Mathf.Lerp(hpSlider.value, m_PerValue, t * 2);
if (Mathf.Abs(hpSlider.value - m_PerValue) <= 0.01f)
m_CurIndex++;
hpSlider.value = 0;
OnIndexUpdate();
else if (m_CurIndex > m_TargetIndex)
hpSlider.value = Mathf.Lerp(hpSlider.value, 0, t * 2);
if (Mathf.Abs(hpSlider.value - 0) <= 0.01f)
m_CurIndex--;
hpSlider.value = m_PerValue;
OnIndexUpdate();
/// <summary>
/// 改变血条数值
/// </summary>
public void ChangeValue(int value)
m_CurHp = (long)Mathf.Clamp(m_CurHp + value, 0, m_TotalHp);
UpdateIndexAndValue();
private void Update()
UpdateHpBar(false);
/// <summary>
/// 血条下标变化后
/// </summary>
void OnIndexUpdate()
UpdateColor();
OnIndexChanged?.Invoke(m_CurIndex, m_CurHp);
以上是关于Unity中实现多层血条的主要内容,如果未能解决你的问题,请参考以下文章