日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

unity3d做会减少的血条_Unity3d中NGUI加强版血条(Healthbar)的制作

發布時間:2025/4/5 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 unity3d做会减少的血条_Unity3d中NGUI加强版血条(Healthbar)的制作 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這陣子項目中需要用到一種特殊樣式的血條。描述如下:

1. 正常顏色為紅色。受到傷害后,即將扣除的血量變暗(暗紅色),并有下降動畫效果;

2. 加護盾效果后,增加一部分血量值,該額外部分為白色,護盾效果消失后該部分血量瞬間消失;

3. 在護盾效果下受到傷害時,首先扣除白色血量。白色血量不足扣除時,余下部分從紅色血量中扣除;

4. 白色血量的扣除效果為變為灰色并有下降動畫效果;

4. 當加護盾效果時,若即將添加的白色血量將使總血條“溢出”,從新計算百分比并排滿血條;

5. 中毒時,將相應的血量(按照傷害扣血優先級,即先扣除護盾,再扣除正常)變為紫色。該紫色血量有遞減動畫;

6. 中毒時若受到傷害,不扣除紫色部分血量(實際上該部分已扣除,但有個緩沖時間),而是紅色或白色部分;

7. 若中毒時受到護盾效果?

8. 血條會自動隱藏,血量產生變化時會自動顯示;

制作普通血條時,我們一般會用UISlider。

但是這里涉及到護盾和中毒的效果,用UISlider顯然是不夠的。我首先想到的是用多個血條疊加在一起,分辨為正常血條、中毒血條、護盾血條。但是掉血效果要怎么解決?

如果只是有下降動畫,那很好解決,可是會先變暗,這顯然是一個slider做不到的。

于是我靈機一動想到了:一個血條,多個UISlider!我們可以寫一個自定義血條,該血條包含正常血量、中毒值、護盾值,以及相應的狀態屬性。

經過實踐,果然我的想法是對的。先來看下效果圖:

1.掉血效果

2.加護盾

2.1 加護盾時掉血

3. 中毒

復雜的疊加效果我們稍后再討論。第一步,先完成UI上的結構設計:

1. Heathbar為金色的邊框(UISprite)

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

3.?ShieldedDmg為加護盾時的減血底色(深灰色)(UISprite, UISlider)

4.?Shielded為護盾顏色(白色)(UISprite, UISlider)

5.?Poisoned為中毒顏色(紫色)(UISprite, UISlider)

6.?NormalDmg為正常情況下的減血底色(暗紅色)(UISprite, UISlider)

7.?Normal為正常血條的顏色(紅色)(UISprite, UISlider)

8.?thumb為血條末端的小刻度(白色)(UISprite),并設置Normal上Slider的Thumb為它

如此,我們就完成了初步的UI設計。數一下,一共有5個Slider。我們再添加一個名為UIHealthbar自定義腳本,用來管理這些UISlider的數值變化,以及處理相關邏輯。

將UIHealthbar綁到Heathbar上。初步腳本如下:

1 usingSystem;2 usingUnityEngine;3

4 public classUIHealthbar : MonoBehaviour5 {6 #region

7

8 privateUISlider _normal;9 privateUISlider _normalDmg;10 privateUISlider _shielded;11 privateUISlider _shieldedDmg;12 privateUISlider _poisoned;13 privateUISprite _barSprite;14

15 #endregion

16

17

18 ///

19 ///全局動畫時長20 ///

21 private const float AnimDuration = 0.2f;22

23 ///

24 ///漸變類型25 ///

26 private const iTween.EaseType EaseType =iTween.EaseType.linear;27

28 ///

29 ///是否正在隱藏或顯示(但如或淡出)30 ///

31 private bool_isFading;32

33 ///

34 ///用來判斷自動隱藏的計時器35 ///

36 private float_timer;37

38 ///

39 ///是否自動隱藏40 ///

41 public bool autoHide = true;42

43 ///

44 ///是否受到正常傷害45 ///

46 private boolIsNormalDamaging47 {48 get { return_normalDmg.gameObject.activeSelf; }49 set{ _normalDmg.gameObject.SetActive(value); }50 }51

52 ///

53 ///是否在加護盾的情況下受到傷害54 ///

55 private boolIsShieldedDamaging56 {57 get { return_shieldedDmg.gameObject.activeSelf; }58 set{ _shieldedDmg.gameObject.SetActive(value); }59 }60

61 ///

62 ///是否正在掉血63 ///

64 public boolIsDamaging65 {66 get { return IsShieldedDamaging ||IsNormalDamaging; }67 }68

69 ///

70 ///是否中毒71 ///

72 public boolIsPoisoned73 {74 get { return_poisoned.gameObject.activeSelf; }75 private set{ _poisoned.gameObject.SetActive(value); }76 }77

78 ///

79 ///是否受護盾80 ///

81 public boolIsShielded82 {83 get { return_shielded.gameObject.activeSelf; }84 private set{ _shielded.gameObject.SetActive(value); }85 }86

87 ///

88 ///是否可見(自動隱藏相關隱藏)89 ///

90 private boolIsVisible91 {92 get

93 {94 throw

95 newNotImplementedException();96 }97 set

98 {99

100 }101 }102

103 private voidOnEnable()104 {105 IsPoisoned = false;106 IsShielded = false;107 IsShieldedDamaging = false;108 IsNormalDamaging = false;109 }110

111 private voidAwake()112 {113 _normal = transform.FindChild("Normal").GetComponent();114 _normalDmg = transform.FindChild("NormalDmg").GetComponent();115 _shielded = transform.FindChild("Shielded").GetComponent();116 _shieldedDmg = transform.FindChild("ShieldedDmg").GetComponent();117 _poisoned = transform.FindChild("Poisoned").GetComponent();118 _barSprite = transform.GetComponent();119 }120

121 #region 邏輯處理

122

123 ///

124 ///加傷害125 ///

126 /// 將造成的傷害百分比(小于1)

127 /// 剩余血量百分比

128 public float AddDamage(floatpercent)129 {130 return 0;131 }132

133 ///

134 ///加中毒值135 ///

136 /// 百分比

137 /// 下降速度(刻度/秒)

138 public void AddPoison(float percent, floatspeed)139 {140 }141

142 ///

143 ///加護盾值144 ///

145 /// 百分比

146 /// 持續時間(秒)

147 public void AddShield(float percent, floattime)148 {149 }150

151 #endregion

152 }

View Code

接下來我們處理具體的邏輯。

1. 自動隱藏:

自動隱藏的需求是,在5秒內未產生任何形式的血量變化,則淡出隱藏。一旦產生血量變化,淡入顯示。

淡入淡出是需要Alpha值來控制的。我們直接改變_barSprite這個字段(即最上層的Healthbar上的UISprite)的alpha值,則其子物體會一起產生Alpha值變化的效果。

修改IsVisible屬性:

1 private boolIsVisible2 {3 get { return _barSprite.color.a >= 1; }4 set

5 {6 _timer = 0;7 if (value != IsVisible && !_isFading)8 {9 _isFading = true;10 if(value)11 {12 iTween.ValueTo(gameObject,13 iTween.Hash("from", 0, "to", 1, "time", AnimDuration, "easetype",14 EaseType, "onupdate", "OnFadeIn",15 "onupdatetarget", gameObject, "oncomplete", "OnFadeInComplete", "oncompletetarget", gameObject));16 }17 else

18 {19 iTween.ValueTo(gameObject,20 iTween.Hash("from", 1, "to", 0, "time", AnimDuration, "easetype",21 EaseType, "onupdate", "OnFadeOut",22 "onupdatetarget", gameObject, "oncomplete", "OnFadeOutComplete", "oncompletetarget", gameObject));23 }24 }25 }26 }

再添加iTween中引用的四個方法:

1 private void OnFadeIn(floatvalue)2 {3 _barSprite.color = new Color(1, 1, 1, value);4 }5

6 private voidOnFadeInComplete()7 {8 _isFading = false;9 _timer = 0;10 }11

12 private void OnFadeOut(floatvalue)13 {14 _barSprite.color = new Color(1, 1, 1, value);15 }16

17 private voidOnFadeOutComplete()18 {19 _isFading = false;20 _timer = 0;21 }

現在,直接改變IsVisible即可控制淡入淡出。我們還需要在Update里檢查血量變化和設置隱藏,即修改IsVisible:

1 private voidUpdate()2 {3 if (autoHide && !_isFading && IsVisible && !IsPoisoned)4 {5 _timer +=Time.deltaTime;6 if (_timer >5f)7 {8 IsVisible = false;9 }10 }11 }

上面設置的閥值為5秒。實際上這個5該提取出來做屬性或字段。在收到傷害,護盾等情況時,我們需要手動改變IsVisible。

2. 減血:

1 ///

2 ///加傷害3 ///

4 /// 將造成的傷害百分比(小于1)

5 /// 剩余血量百分比

6 public float AddDamage(floatpercent)7 {8 if (!IsVisible)9 {10 IsVisible = true;11 }12 if (percent >1f)13 {14 Debug.LogWarning(string.Format("Illegal damage percent: -{0}", percent));15 return_normal.value;16 }17 if (_normal.value <=0f)18 {19 Debug.LogWarning(string.Format("Health is already below zero: -{0}", percent));20 return_normal.value;21 }22 if(IsShielded)23 {24 _shieldedDmg.value =_shielded.value;25 _shielded.value -=percent;26 _shieldedDmg.gameObject.SetActive(true);27 iTween.ValueTo(gameObject,28 iTween.Hash("from", _shieldedDmg.value, "to", _shielded.value, "time", AnimDuration, "easetype",29 EaseType, "onupdate", "OnShieldedDamage",30 "onupdatetarget", gameObject, "oncomplete", "ShieldedDamageDone", "oncompletetarget", gameObject));31 //if damage lows the shield value to zero, take health instead32 //...

33 }34 else

35 {36 _normalDmg.value =_normal.value;37 _normal.value -=percent;38 _normalDmg.gameObject.SetActive(true);39 iTween.ValueTo(gameObject,40 iTween.Hash("from", _normalDmg.value, "to", _normal.value, "time", AnimDuration, "easetype", EaseType,41 "onupdate", "OnNormalDamage",42 "onupdatetarget", gameObject, "oncomplete", "NormalDamageDone", "oncompletetarget", gameObject));43 }44

45 return_normal.value;46 }

上面有判斷護盾。當受到的傷害不大于護盾值時,只會減少護盾,若未大于護盾值,則會從正常血量里扣除剩余的值(此處我未處理這種情況。只標了注釋,算是留給大家的一個題目...)。

注意,血量值得變化是按百分比來算的。所以各種參數應該在折算后傳入。比如你滿血為100,受到20點傷害,那么應該AddDamage(0.2f);

添加iTween里的引用:

1 private void OnNormalDamage(floatvalue)2 {3 _normalDmg.value =value;4 }5

6 private voidNormalDamageDone()7 {8 _normalDmg.gameObject.SetActive(false);9 }10

11 private void OnShieldedDamage(floatvalue)12 {13 _shieldedDmg.value =value;14 }15

16 private voidShieldedDamageDone()17 {18 _shieldedDmg.gameObject.SetActive(false);19 }

注意在變化完成,及時隱藏相關底色。

3. 護盾:

1 ///

2 ///加護盾值3 ///

4 /// 百分比

5 /// 持續時間(秒)

6 public void AddShield(float percent, floattime)7 {8 //若將增加的護盾值使總值超過100%

9 if (_normal.value + percent + _shieldMod >1f)10 {11 percent = _normal.value + percent + _shieldMod - 1;12 _normal.value -=percent;13 _shieldMod +=percent;14 }15 //若已中毒

16 if(IsPoisoned)17 {18 //若將要增加的護盾值大于中毒(剩余)值

19 if (percent >_poisoned.value)20 {21 percent -=_poisoned.value;22 }23 else //否則

24 {25 percent = percent -_poisoned.value;26 }27 }28 _shielded.value = _normal.value +percent;29 IsShielded = true;30 iTween.ValueTo(gameObject,31 iTween.Hash("from", 0, "to", time, "time", time, "onupdate", "OnShield", "oncomplete", "ShieldTimeOut",32 "oncompleteparams", _shieldMod,33 "oncompletetarget", gameObject));34 }

上面出現里一個float型的_shieldMod之前并沒有聲明。事實上我后來了解到需求里護盾是不能疊加的,后加的護盾只會覆蓋之前的護盾。所以這個用來存儲多重護盾值得_shieldMod就沒用了。移除即可。記得要從iTween.ValueTo里也將其移除并修改對應方法簽名(ShieldTimeOut)。

1 private void OnShield(floatvalue)2 {3 }4

5 private void ShieldTimeOut(floatmodPercent)6 {7 _shieldMod = Mathf.Max(0, _shieldMod -modPercent);8 _normal.value +=modPercent;9 IsShielded = false;10 _shielded.value =_normal.value;11 _shieldedDmg.value =_normal.value;12 }

護盾到期是在ShieldTimeOut里處理的。此處并沒有漸變消失,而是啪一下沒了=。=

4.中毒:

1 ///

2 ///加中毒值3 ///

4 /// 百分比

5 /// 下降速度(刻度/秒)

6 public void AddPoison(float percent, floatspeed)7 {8 //若已加護盾

9 if(IsShielded)10 {11 //若將要增加的中毒值大于護盾值

12 if (percent >_shielded.value)13 {14 percent -=_shielded.value;15 }16 else //否則

17 {18 percent = _shielded.value -percent;19 }20 }21 if (percent < 0)22 {23 return;24 }25 _normal.value -=percent;26 IsPoisoned = true;27 iTween.ValueTo(gameObject,28 iTween.Hash("from", percent, "to", 0, "speed", speed, "easetype", EaseType, "onupdate", "OnPoison", "onupdatetarget",29 gameObject,30 "oncomplete",31 "PoisonTimeOut",32 "oncompletetarget", gameObject));33 }

1 private void OnPoison(floatvalue)2 {3 _poisoned.value = _normal.value +value;4 }5

6 private voidPoisonTimeOut()7 {8 IsPoisoned = false;9 _poisoned.value =_normal.value;10 }

中毒的遞減效果在OnPoison里實現。

最后添加測試代碼:

1 ///

2 ///Debug Testing3 ///

4 private voidOnGUI()5 {6 if (GUI.Button(new Rect(10, 10, 200, 100), "Hit - 20%"))7 {8 AddDamage(0.2f);9 }10 if (GUI.Button(new Rect(10, 120, 200, 100), "Shield + 30%(3s)"))11 {12 AddShield(0.3f, 3);13 }14 if (GUI.Button(new Rect(10, 230, 200, 100), "Poison + 10%(5%/s)"))15 {16 AddPoison(0.1f, 0.05f);17 }18 }

到此就差不多完成了。拖出來當預置,就成了一個自定義控件。

事實上還存在許多bug。尤其是在面臨【又加護盾又中毒又受傷害】這類情況下。我沒有去處理這樣的邏輯因為項目里不需要。這里只是提供一個思路給大家。如果能拋磚引玉當然最好了~

另外,里面的iTween這樣用起來會很麻煩。我會另寫一篇,介紹我的iTween自定義擴展。

源碼請見我的github。

https://github.com/theoxuan/GeneralGame/blob/master/Assets/Resources/Healthbar.prefab

https://github.com/theoxuan/GeneralGame/blob/master/Assets/Script/UIHealthbar.cs

總結

以上是生活随笔為你收集整理的unity3d做会减少的血条_Unity3d中NGUI加强版血条(Healthbar)的制作的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。