前言
原文鏈接: https://www.yuque.com/finctive/game-dev/obsever-ugui
本文參考自:
- Unity3d College - Observer Pattern - Game Programming Patterns in Unity & C#(視頻教程)
- 游戲設計模式-觀察者模式 (譯文)
- Game Programming Patterns - Observer (英語原文)
在閱讀完本文后,請查看上述鏈接內容。
本文使用的示例工程:FINCTIVE/lost-in-the-wilderness-nightmare(荒野迷蹤:噩夢)歡迎Star赂摆!
由于水平有限,文章內容可能有誤抠藕,歡迎探討、交流蒋困、或直接批評盾似。
┗|`O′|┛
本文作者: FINCTIVE
聯(lián)系郵箱: finctive@qq.com
轉載請標明原文鏈接以及作者名字,謝謝雪标。
應用場景
想象你在游戲項目中實現(xiàn)了一個角色控制器零院,這個控制器相對復雜,以至于你想新開一個空場景來單獨測試這個控制器腳本村刨。
很不幸告抄,你發(fā)現(xiàn)在新場景中,角色游戲對象缺乏相關UI的引用嵌牺,導致程序無法測試打洼。
public Slider hpSlider; // 舉個例子,角色HP的血條
void GetDamage()
{
// ...處理受傷代碼...
// 更新相應UI
hpSlider.value = newValue; // 在新場景中導致空引用
}
解決方案
使用C#委托和事件來建立hp更新和UI更新的聯(lián)系逆粹。
在管理玩家屬性的腳本中(本例中是PlayerInfo.cs)
public event Action<int> OnPlayerHpChange;
public int hp
{
get => _hp;
set
{
_hp = value;
if (OnPlayerHpChange != null)
OnPlayerHpChange(_hp);
}
}
在控制UI更新行為的腳本中(本例是PlayerHpUI.cs)
void Start()
{
// 通過全局變量獲取player示例中的playerInfo對象(與上一個代碼示例對應)
PlayerController.player.playerInfo.OnPlayerHpChange += _OnPlayerHpChange;
}
private void _OnPlayerHpChange(int hp)
{
hpSlider.value = (float)hp / 100f;
}
在本例中Player控制器部分代碼與UI更新代碼分離開了募疮,實際工程項目中會出現(xiàn)更復雜的情況;本文例子是“一對一”的情況僻弹,實際工程中有可能會出現(xiàn)“一對多”甚至“多對多”的情況阿浓。
更經典的應用場景是游戲成就系統(tǒng):游戲成就千奇百怪,把判定游戲成就的代碼耦合到其他游戲系統(tǒng)中不是一個明智的做法蹋绽。
作者:FINCTIVE(finctive@qq.com)
歡迎轉載芭毙,請附上原文鏈接以及作者名字,謝謝卸耘!