这阵子项目中需要用到一种特殊样式的血条。描述如下:

1. 正常颜色为红色。受到伤害后,即将扣除的血量变暗(暗红色),并有下降动画效果;

2. 加护盾效果后,增加一部分血量值,该额外部分为白色,护盾效果消失后该部分血量瞬间消失;

3. 在护盾效果下受到伤害时,首先扣除白色血量。白色血量不足扣除时,余下部分从红色血量中扣除;

4. 白色血量的扣除效果为变为灰色并有下降动画效果;

4. 当加护盾效果时,若即将添加的白色血量将使总血条“溢出”,从新计算百分比并排满血条;

5. 中毒时,将相应的血量(按照伤害扣血优先级,即先扣除护盾,再扣除正常)变为紫色。该紫色血量有递减动画;

6. 中毒时若受到伤害,不扣除紫色部分血量(实际上该部分已扣除,但有个缓冲时间),而是红色或白色部分;

7. 若中毒时受到护盾效果?

8. 血条会自动隐藏,血量产生变化时会自动显示;

 

制作普通血条时,我们一般会用UISlider。

但是这里涉及到护盾和中毒的效果,用UISlider显然是不够的。我首先想到的是用多个血条叠加在一起,分辨为正常血条、中毒血条、护盾血条。但是掉血效果要怎么解决?

如果只是有下降动画,那很好解决,可是会先变暗,这显然是一个slider做不到的。

于是我灵机一动想到了:一个血条,多个UISlider!我们可以写一个自定义血条,该血条包含正常血量、中毒值、护盾值,以及相应的状态属性。

经过实践,果然我的想法是对的。先来看下效果图:

1.掉血效果

 Unity3d中NGUI加强版血条(Healthbar)的制作

Unity3d中NGUI加强版血条(Healthbar)的制作

2.加护盾

Unity3d中NGUI加强版血条(Healthbar)的制作

2.1 加护盾时掉血

Unity3d中NGUI加强版血条(Healthbar)的制作

3. 中毒

Unity3d中NGUI加强版血条(Healthbar)的制作

 

复杂的叠加效果我们稍后再讨论。第一步,先完成UI上的结构设计:

Unity3d中NGUI加强版血条(Healthbar)的制作

1. Heathbar为金色的边框(UISprite)

Unity3d中NGUI加强版血条(Healthbar)的制作

2. Blank为底色(灰)(UISprite)

Unity3d中NGUI加强版血条(Healthbar)的制作

3. ShieldedDmg为加护盾时的减血底色(深灰色)(UISprite, UISlider)

Unity3d中NGUI加强版血条(Healthbar)的制作

4. Shielded为护盾颜色(白色)(UISprite, UISlider)

Unity3d中NGUI加强版血条(Healthbar)的制作

5. Poisoned为中毒颜色(紫色)(UISprite, UISlider)

Unity3d中NGUI加强版血条(Healthbar)的制作

6. NormalDmg为正常情况下的减血底色(暗红色)(UISprite, UISlider)

Unity3d中NGUI加强版血条(Healthbar)的制作

7. Normal为正常血条的颜色(红色)(UISprite, UISlider)

Unity3d中NGUI加强版血条(Healthbar)的制作

8. thumb为血条末端的小刻度(白色)(UISprite),并设置Normal上Slider的Thumb为它

Unity3d中NGUI加强版血条(Healthbar)的制作

 

如此,我们就完成了初步的UI设计。数一下,一共有5个Slider。我们再添加一个名为UIHealthbar自定义脚本,用来管理这些UISlider的数值变化,以及处理相关逻辑。

将UIHealthbar绑到Heathbar上。初步脚本如下:

  1 using System;
  2 using UnityEngine;
  3 
  4 public class UIHealthbar : MonoBehaviour
  5 {
  6     #region 
  7 
  8     private UISlider _normal;
  9     private UISlider _normalDmg;
 10     private UISlider _shielded;
 11     private UISlider _shieldedDmg;
 12     private UISlider _poisoned;
 13     private UISprite _barSprite;
 14 
 15     #endregion
 16 
 17 
 18     /// <summary>
 19     /// 全局动画时长
 20     /// </summary>
 21     private const float AnimDuration = 0.2f;
 22 
 23     /// <summary>
 24     /// 渐变类型
 25     /// </summary>
 26     private const iTween.EaseType EaseType = iTween.EaseType.linear;
 27 
 28     /// <summary>
 29     /// 是否正在隐藏或显示(但如或淡出)
 30     /// </summary>
 31     private bool _isFading;
 32 
 33     /// <summary>
 34     /// 用来判断自动隐藏的计时器
 35     /// </summary>
 36     private float _timer;
 37 
 38     /// <summary>
 39     /// 是否自动隐藏
 40     /// </summary>
 41     public bool autoHide = true;
 42 
 43     /// <summary>
 44     /// 是否受到正常伤害
 45     /// </summary>
 46     private bool IsNormalDamaging
 47     {
 48         get { return _normalDmg.gameObject.activeSelf; }
 49         set { _normalDmg.gameObject.SetActive(value); }
 50     }
 51 
 52     /// <summary>
 53     /// 是否在加护盾的情况下受到伤害
 54     /// </summary>
 55     private bool IsShieldedDamaging
 56     {
 57         get { return _shieldedDmg.gameObject.activeSelf; }
 58         set { _shieldedDmg.gameObject.SetActive(value); }
 59     }
 60 
 61     /// <summary>
 62     /// 是否正在掉血
 63     /// </summary>
 64     public bool IsDamaging
 65     {
 66         get { return IsShieldedDamaging || IsNormalDamaging; }
 67     }
 68 
 69     /// <summary>
 70     /// 是否中毒
 71     /// </summary>
 72     public bool IsPoisoned
 73     {
 74         get { return _poisoned.gameObject.activeSelf; }
 75         private set { _poisoned.gameObject.SetActive(value); }
 76     }
 77 
 78     /// <summary>
 79     /// 是否受护盾
 80     /// </summary>
 81     public bool IsShielded
 82     {
 83         get { return _shielded.gameObject.activeSelf; }
 84         private set { _shielded.gameObject.SetActive(value); }
 85     }
 86 
 87     /// <summary>
 88     /// 是否可见(自动隐藏相关隐藏)
 89     /// </summary>
 90     private bool IsVisible
 91     {
 92         get
 93         {
 94             throw
 95                 new NotImplementedException();
 96         }
 97         set
 98         {
 99             
100         }
101     }
102 
103     private void OnEnable()
104     {
105         IsPoisoned = false;
106         IsShielded = false;
107         IsShieldedDamaging = false;
108         IsNormalDamaging = false;
109     }
110 
111     private void Awake()
112     {
113         _normal = transform.FindChild("Normal").GetComponent<UISlider>();
114         _normalDmg = transform.FindChild("NormalDmg").GetComponent<UISlider>();
115         _shielded = transform.FindChild("Shielded").GetComponent<UISlider>();
116         _shieldedDmg = transform.FindChild("ShieldedDmg").GetComponent<UISlider>();
117         _poisoned = transform.FindChild("Poisoned").GetComponent<UISlider>();
118         _barSprite = transform.GetComponent<UISprite>();
119     }
120 
121     #region 逻辑处理
122 
123     /// <summary>
124     /// 加伤害
125     /// </summary>
126     /// <param name="percent">将造成的伤害百分比(小于1)</param>
127     /// <returns>剩余血量百分比</returns>
128     public float AddDamage(float percent)
129     {
130         return 0;
131     }
132 
133     /// <summary>
134     /// 加中毒值
135     /// </summary>
136     /// <param name="percent">百分比</param>
137     /// <param name="speed">下降速度(刻度/秒)</param>
138     public void AddPoison(float percent, float speed)
139     {
140     }
141 
142     /// <summary>
143     /// 加护盾值
144     /// </summary>
145     /// <param name="percent">百分比</param>
146     /// <param name="time">持续时间(秒)</param>
147     public void AddShield(float percent, float time)
148     {
149     }
150 
151     #endregion
152 }
View Code

相关文章: