Unity 3D | 游戏UI中使用观察者模式

前言

原文链接: 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
联系邮箱: [email protected]

转载请标明原文链接以及作者名字,谢谢。

应用场景

想象你在游戏项目中实现了一个角色控制器,这个控制器相对复杂,以至于你想新开一个空场景来单独测试这个控制器脚本。

很不幸,你发现在新场景中,角色游戏对象缺乏相关UI的引用,导致程序无法测试。

public Slider hpSlider; // 举个例子,角色HP的血条
void GetDamage()
{
    // ...处理受伤代码...
    // 更新相应UI
    hpSlider.value = newValue; // 在新场景中导致空引用
}

解决方案

使用C#委托和事件来建立hp更新和UI更新的联系。

在管理玩家属性的脚本中(本例中是PlayerInfo.cs)

public event Action 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更新代码分离开了,实际工程项目中会出现更复杂的情况;本文例子是“一对一”的情况,实际工程中有可能会出现“一对多”甚至“多对多”的情况。

更经典的应用场景是游戏成就系统:游戏成就千奇百怪,把判定游戏成就的代码耦合到其他游戏系统中不是一个明智的做法。

作者:FINCTIVE([email protected])
欢迎转载,请附上原文链接以及作者名字,谢谢!

你可能感兴趣的:(Unity 3D | 游戏UI中使用观察者模式)