//--------------------------------------------------------
|
// [Author]: 第二世界
|
// [ Date ]: Monday, September 11, 2017
|
//--------------------------------------------------------
|
using UnityEngine;
|
using System.Collections;
|
using UnityEngine.UI;
|
|
using System.Text;
|
|
public class BossLifeBar : MonoBehaviour
|
{
|
[SerializeField] Sprite[] m_LifeBarSprites;
|
|
[SerializeField] Image m_BackGround;
|
[SerializeField] Image m_MiddleGround;
|
[SerializeField] Image m_PrefaceGround;
|
|
[SerializeField] Slider m_SliderMiddleground;
|
[SerializeField] Slider m_SliderForeground;
|
|
[SerializeField] Text m_Surplus;
|
|
[SerializeField] Text m_SurplusPercent;
|
|
|
[SerializeField] float m_SmoothTime = 0.3f;
|
public float smoothTime {
|
get { return m_SmoothTime; }
|
}
|
|
Pattern pattern = Pattern.Reduce;
|
float targetValue = 0f;
|
int totalSegments = 1;
|
int surplusSegments = -1;
|
|
float refValue = 0f;
|
float timer = 0f;
|
float behaviourStartValue = 0f;
|
|
float m_CurrentBehaviourValue = 0f;
|
float currentBehaviourValue {
|
get { return m_CurrentBehaviourValue; }
|
set {
|
m_CurrentBehaviourValue = value;
|
UpdateSurplusSegments(currentBehaviourValue);
|
|
float behaviourDecimalValue = GetSegmentDecimal(m_CurrentBehaviourValue);
|
float trueDecimalValue = GetSegmentDecimal(targetValue);
|
|
switch (pattern)
|
{
|
case Pattern.Add:
|
m_SliderForeground.value = behaviourDecimalValue;
|
m_SliderMiddleground.value = behaviourDecimalValue > trueDecimalValue ? 1f : trueDecimalValue;
|
break;
|
case Pattern.Reduce:
|
m_SliderMiddleground.value = behaviourDecimalValue;
|
m_SliderForeground.value = behaviourDecimalValue < trueDecimalValue ? 0f : trueDecimalValue;
|
break;
|
case Pattern.None:
|
m_SliderMiddleground.value = behaviourDecimalValue;
|
m_SliderForeground.value = behaviourDecimalValue;
|
break;
|
}
|
}
|
}
|
|
public void SetBaseInfo(int _lifeBarCount, ulong _hp, ulong _maxHp)
|
{
|
surplusSegments = -1;
|
totalSegments = _lifeBarCount;
|
|
// 使用精确值,不再人为减小
|
float percentage = (_maxHp > 0) ? (float)_hp / (float)_maxHp : 0f;
|
targetValue = currentBehaviourValue = percentage * totalSegments;
|
|
// 使用统一的 GetSegmentDecimal,避免小数精度导致进度条为0
|
var behaviourDecimalValue = GetSegmentDecimal(currentBehaviourValue);
|
m_SliderForeground.value = m_SliderMiddleground.value = behaviourDecimalValue;
|
|
refValue = 0f;
|
|
// 立刻显示基准百分比(使用 percentage)
|
m_SurplusPercent.text = (percentage * 100f).ToString("F2") + "%";
|
}
|
|
public void Show(ulong _hp, ulong _maxHp)
|
{
|
var percentage = Mathf.Clamp(_hp, 0, _maxHp) / (float)_maxHp;
|
var tempValue = totalSegments * percentage; // 不再减小
|
pattern = tempValue > targetValue ? Pattern.Add : tempValue < targetValue ? Pattern.Reduce : Pattern.None;
|
|
behaviourStartValue = currentBehaviourValue;
|
targetValue = tempValue;
|
|
timer = 0f;
|
refValue = 0f;
|
|
// 立即更新百分比显示(直接使用 percentage)
|
m_SurplusPercent.text = (percentage * 100f).ToString("F2") + "%";
|
}
|
|
private void LateUpdate()
|
{
|
if (Mathf.Abs(currentBehaviourValue - targetValue) > 0.00001f)
|
{
|
var newValue = Mathf.SmoothDamp(currentBehaviourValue, targetValue, ref refValue, smoothTime);
|
currentBehaviourValue = newValue;
|
}
|
}
|
|
static StringBuilder stringBuild = new StringBuilder();
|
private void UpdateSurplusSegments(float _targetValue)
|
{
|
var currentSurplus = Mathf.CeilToInt(_targetValue);
|
if (currentSurplus != surplusSegments)
|
{
|
surplusSegments = currentSurplus;
|
var colorSetLength = m_LifeBarSprites.Length;
|
var index = surplusSegments % colorSetLength;
|
var nextIndex = index == 0 ? colorSetLength - 1 : index - 1;
|
|
m_PrefaceGround.overrideSprite = m_LifeBarSprites[index];
|
m_MiddleGround.overrideSprite = m_LifeBarSprites[index];
|
m_BackGround.overrideSprite = m_LifeBarSprites[nextIndex];
|
|
m_BackGround.SetActive(surplusSegments > 1);
|
|
m_Surplus.text = "x" + surplusSegments.ToString();
|
float pct = totalSegments > 0 ? Mathf.Clamp01(_targetValue / totalSegments) : 0f;
|
// 修复格式并处理接近 100% 的情况
|
if (1f - pct < 0.00005f) pct = 1f;
|
m_SurplusPercent.text = (pct * 100f).ToString("F2") + "%";
|
}
|
}
|
|
// int GetNumKey(int _num)
|
// {
|
// var config = DamageNumConfig.Get("BossLifeBarSurplusNum");
|
// return config.nums[_num - 48];
|
// }
|
|
|
enum Pattern
|
{
|
None,
|
Add,
|
Reduce,
|
}
|
|
// helper: 返回段内小数部分;当恰好为整数且大于0时,返回1以表示满格(避免0导致进度条变空)
|
private float GetSegmentDecimal(float value)
|
{
|
if (value <= 0f) return 0f;
|
|
// 使用一个小的容忍值来处理浮点误差,避免 near-integer 导致 0
|
const float eps = 1e-5f;
|
|
// 先做一个向下稳定的 floor,避免 2.999999 变成 2 的问题
|
float stableFloor = Mathf.Floor(value + eps);
|
float frac = value - stableFloor;
|
|
if (frac <= eps)
|
return 1f; // 视为整段,显示满格
|
return Mathf.Clamp01(frac);
|
}
|
|
}
|