小白笔记二:UGUI的渐变血条设计(遮罩层实现)

看过几篇讲解UGUI的教程,基本每一篇后面的实例中都会教如何用slider组件实现血条,甚至笔者买了一本有关unity的书,在介绍UGUI的时候也要提一下slider实现血条的事。

但是,slider实现的血条真的好用吗?

slider实现的血条对于初学者很友好,一看就懂,用起来也很方便,但是它本质上通过控制缩放实现的方式在很多情况又不是很好用,比如:你要实现的血条不是纯色的,而是美术交给你的精美绝伦的图片时。

本文将展示一种使用RectMask2D组件实现的血条设计。

演示效果:

组件截图:

 Hp添加Bar脚本;Hp两个儿子添加RectMask2D组件;Hp两个孙子添加Image组件(hp图片资源)和HorizontalLayoutGroup组件(为了添加每百血分割线准备的)配置如下:

 最后把对应的组件添加到脚本上即可。

代码如下:

using UnityEngine;
using UnityEngine.UI;

namespace ETModel
{
    [DisallowMultipleComponent]
    [RequireComponent(typeof(RectTransform))]
    public class Bar : MonoBehaviour
    {
        [Range(0.0f, 1.0f)]
        [Tooltip("血条剩余血量占比")]
        public float Alpha = 1.0f;
        [Tooltip("血条遮罩层组件")]
        public RectTransform FillRectTrans;
        [Tooltip("血条组件")]
        public RectTransform HpFillRectTrans;
        [Tooltip("渐变血条遮罩层组件")]
        public RectTransform TweenRectTrans;
        [Tooltip("渐变血条组件")]
        public RectTransform HpTweenRectTrans;
        [Tooltip("满血血量数值")]
        public int BloodVolume;
        [Tooltip("当前血量数值")]
        [HideInInspector]
        public float CurrentBlood;
        [Tooltip("每一百血量分割线")]
        public Sprite CutLine;

        private float tempBlood;
        private float newBlood;
        private float tweenSpeed;
        private bool isHurt;
        private float time;
        private float width;

        public void Awake()
        {
            InitData();
            DrawLine();
        }

        public void Update()
        {
            FillRectTrans.GetComponent<RectMask2D>().padding = new Vector4(0, 0, (1 - Alpha) * width, 0);
            TweenRectTrans.GetComponent<RectMask2D>().padding = new Vector4(0, 0, width - CurrentBlood * width / BloodVolume, 0);

            if (CurrentBlood != Alpha * BloodVolume)
            {
                if (!isHurt)
                {
                    isHurt = true;
                    tempBlood = newBlood;
                    newBlood = Alpha * BloodVolume;
                }
                else
                { 
                    time = 0;
                    tempBlood = CurrentBlood;
                    newBlood = Alpha * BloodVolume;
                }
            }
            if(isHurt)
            {
                time = time >= 1 ? 1 : time+ tweenSpeed * Time.deltaTime;
                CurrentBlood = Mathf.Lerp(tempBlood, newBlood, time);
                if (time == 1)
                {
                    isHurt = false;
                    time = 0;
                }
            }
        }

        private void InitData()
        {
            Alpha = 1.0f;
            tweenSpeed = 2.0f;
            newBlood = BloodVolume;
            CurrentBlood = BloodVolume;
            time = 0;
            isHurt = false;
            width = HpFillRectTrans.sizeDelta.x;
        }

        private void DrawLine()
        {
            if (BloodVolume != 0)
            { 
                int lineCount = BloodVolume / 100;
                float singleHundred = HpFillRectTrans.sizeDelta.x * 100 / BloodVolume;
                HpFillRectTrans.GetComponent<HorizontalLayoutGroup>().padding.left = (int)singleHundred;
                HpTweenRectTrans.GetComponent<HorizontalLayoutGroup>().padding.left = (int)singleHundred;
                HpFillRectTrans.GetComponent<HorizontalLayoutGroup>().spacing = singleHundred;
                HpTweenRectTrans.GetComponent<HorizontalLayoutGroup>().spacing = singleHundred;
                CreatLine(lineCount, HpFillRectTrans.transform);
                CreatLine(lineCount, HpTweenRectTrans.transform);
            }
        }

        private void CreatLine(int number , Transform parent)
        {
            for (int i = 0; i < number; i++)
            {
                GameObject go = new GameObject();
                Image image = go.AddComponent<Image>();
                image.sprite = CutLine;
                go.transform.SetParent(parent, false);
            }
        }

        void OnGUI()
        {
            if (GUI.Button(new Rect(800, 50, 80, 20), "掉血"))
                Alpha -= 0.1f;
            if (GUI.Button(new Rect(800, 30, 80, 20), "回复"))
            {
                Alpha = 1.0f;
                InitData();
            }
        }
    }
}

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

半步开发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值