IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity中实现多层血条 -> 正文阅读

[游戏开发]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_CurIndex = m_ColorList.Count;
        m_PerValue = m_TotalHp * 1f / m_ColorList.Count;
        hpSlider.minValue = 0;
        hpSlider.maxValue = m_PerValue;
        hpSlider.value = m_PerValue;

        UpdateIndexAndValue();
        UpdateHpBar(true);
        UpdateColor();
        OnValueChanged?.Invoke(m_CurIndex, m_CurHp);
    }

    /// <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
            ? 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_TargetIndex >= m_ColorList.Count
            && m_CurHp % m_PerValue == 0)
        {
            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;
        }
        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);
                    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);
                    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);
    }
}
  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-02-03 01:27:13  更:2022-02-03 01:27:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 18:21:16-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码