加载中...

【Unity系列】新手做游戏需要了解如何在游戏中应用“开发模式”

  • 2025-08-21
  • 游戏开发
  • unity教程 游戏开发
  • --

在游戏开发中,随着功能不断增加,脚本之间的关系往往会越来越复杂。角色要通知UI更新血量,UI要触发音效,任务系统又要依赖角色状态。如果所有逻辑都通过直接调用来实现,代码很快会陷入混乱。这也是为什么需要“开发模式”来帮助我们组织结构。

这次我们介绍两种常见且实用的模式:单例模式和事件驱动模式。

单例模式(Singleton)

在Unity项目中,经常需要全局唯一的管理类,例如声音管理器(AudioManager)或配置管理器(ConfigManager)。这类对象在场景中只需要一个实例,且需要在任意地方方便访问。

一个简单的单例写法如下:

publicclassAudioManager : MonoBehaviour {
publicstatic AudioManager Instance {
get;
privateset;
}
voidAwake(){
    if (Instance == null) {
        Instance = this;
        DontDestroyOnLoad(gameObject);
    }
    else {
        Destroy(gameObject);
    }
}
publicvoidPlaySound(string name){
    // 播放音效逻辑        
}
}

这样,在任意脚本中只需 AudioManager.Instance.PlaySound("hit"); 即可调用。

优点 :实现简单,全局访问方便。

缺点 :滥用会导致过度依赖,降低模块独立性。

事件驱动模式(Event System)

当多个对象需要同时响应某个变化时,直接调用往往显得笨拙。例如角色掉血,既要更新UI,又要播放音效,还可能触发Boss的行为。如果逐一调用,不仅耦合度高,而且修改困难。

事件驱动模式提供了解耦的方式:对象不再直接调用彼此,而是通过事件广播与监听进行通信。

一个常见实现是使用C#的 Action:

publicclassPlayer : MonoBehaviour {
    publicstatic event Action<int> OnHealthChanged;
    privateint health = 100;
    publicvoidTakeDamage(int damage){
        health -= damage;
        OnHealthChanged?.Invoke(health);
    }
}

UI脚本可以这样订阅:

voidOnEnable(){
    Player.OnHealthChanged += UpdateHealthBar;
}
voidOnDisable(){
    Player.OnHealthChanged -= UpdateHealthBar;
}
voidUpdateHealthBar(int hp){
    // 更新血条UI
}

当角色掉血时,UI、音效、Boss逻辑都能各自订阅并独立响应,而无需互相知道对方的存在。

优点 :解耦,扩展性强。

缺点 :事件关系复杂时调试不便,需要良好命名和管理。

综合应用

可以将单例模式和事件驱动结合起来,创建一个全局的事件中心(EventManager)。EventManager 本身是一个单例,负责管理和广播所有的游戏事件。

实战小案例

假设有这样一个场景:主角掉血 → UI血条自动更新 → 音效触发 → Boss触发特殊状态。

如果不用设计模式来写,需要在 Player 掉血时,分别调用 UI 血条、音效管理器和 Boss 的相应函数,代码耦合度高。

而使用事件驱动,只需要在 Player 掉血时,触发 OnPlayerHealthChanged 事件,UI、音效和 Boss 都可以自动响应,代码更加简洁清晰。

小结

单例 :适合全局唯一的对象,如管理器类。

事件驱动 :适合多人监听的场景,降低耦合。

组合 :单例事件中心在中小型项目中非常常见。

合理使用这些模式,可以让项目在复杂度提升时依然保持清晰。下一篇我们将介绍 ScriptableObject 的数据驱动用法,它能进一步简化配置和数据管理。

Maple
Maple
© 2025 by Maplezz 本文基于 CC BY-NC-SA 4.0 许可 CC 协议 必须注明创作者 仅允许将作品用于非商业用途 改编作品必须遵循相同条款进行共享 最后更新:2025/8/22