Unity 中介者模式 (实例详解)

文章目录

简介

在Unity游戏开发中,中介者(Mediator)模式用于降低多个对象之间的耦合度,通过引入一个中介类来封装和管理对象间的交互。下面我将提供五个简化的代码实例来说明如何在Unity项目中应用中介者模式:

实例1:玩家与UI交互

csharp 复制代码
// 定义用户界面组件接口
public interface IUiComponent
{
    void UpdateHealth(int health);
    void UpdateScore(int score);
}

// 玩家类,实现UI组件接口的更新方法调用
public class Player : MonoBehaviour
{
    private Mediator _mediator;

    public void SetMediator(Mediator mediator)
    {
        _mediator = mediator;
    }

    // 当玩家生命值改变时,通知中介者更新UI
    public void ChangeHealth(int amount)
    {
        int newHealth = GetHealth() + amount;
        _mediator.UpdateHealth(newHealth);
    }

    // 获取当前生命值的方法(实际项目中会有具体实现)
    private int GetHealth() { return 100; }
}

// UI面板类,实现IUiComponent接口
public class HealthAndScoreUI : MonoBehaviour, IUiComponent
{
    public void UpdateHealth(int health)
    {
        // 更新UI显示的生命值
        Debug.Log("Updating health to: " + health);
    }

    public void UpdateScore(int score)
    {
        // 更新UI显示的分数
        Debug.Log("Updating score to: " + score);
    }
}

// 中介者类
public class Mediator
{
    private IUiComponent _ui;

    public void RegisterUi(IUiComponent ui)
    {
        _ui = ui;
    }

    public void UpdateHealth(int health)
    {
        if (_ui != null)
            _ui.UpdateHealth(health);
    }

    // 同理可以定义UpdateScore等方法
}

// 在场景初始化或Awake阶段进行关联
public class GameManager : MonoBehaviour
{
    public Mediator Mediator;
    public Player Player;
    public HealthAndScoreUI HealthScoreUI;

    void Start()
    {
        Player.SetMediator(Mediator);
        Mediator.RegisterUi(HealthScoreUI);
    }
}

实例2:战斗模块中的攻击事件协调

csharp 复制代码
public interface IBattleParticipant
{
    void ReceiveDamage(int damage);
    void Attack(IBattleParticipant target);
}

public class Warrior : MonoBehaviour, IBattleParticipant
{
    private Mediator _mediator;

    public void SetMediator(Mediator mediator)
    {
        _mediator = mediator;
    }

    public void AttackButtonClicked()
    {
        _mediator.Attack(this);
    }

    public void ReceiveDamage(int damage)
    {
        // 实际处理伤害逻辑
    }

    public void Attack(IBattleParticipant target)
    {
        // 计算并发出攻击
        int attackDamage = CalculateAttackDamage();
        _mediator.DistributeDamage(this, target, attackDamage);
    }
    
    // 其他战斗相关方法...
}

public class BattleMediator
{
    private List<IBattleParticipant> _participants;

    public void RegisterParticipant(IBattleParticipant participant)
    {
        _participants.Add(participant);
    }

    public void DistributeDamage(IBattleParticipant attacker, IBattleParticipant defender, int damage)
    {
        defender.ReceiveDamage(damage);
    }

    // 其他战斗协调逻辑...
}

实例3:游戏场景中的事件广播

csharp 复制代码
public class SceneMediator
{
    private List<IMediatorListener> _listeners;

    public void RegisterListener(IMediatorListener listener)
    {
        _listeners.Add(listener);
    }

    public void UnregisterListener(IMediatorListener listener)
    {
        _listeners.Remove(listener);
    }

    public void NotifyPlayerJoined(Player player)
    {
        foreach (var listener in _listeners)
        {
            listener.OnPlayerJoined(player);
        }
    }

    // 其他事件通知方法...
}

public interface IMediatorListener
{
    void OnPlayerJoined(Player player);
}

public class ScoreKeeper : MonoBehaviour, IMediatorListener
{
    public void OnPlayerJoined(Player player)
    {
        // 更新玩家加入后的得分信息
    }
}

public class ChatManager : MonoBehaviour, IMediatorListener
{
    public void OnPlayerJoined(Player player)
    {
        // 在聊天频道广播玩家加入消息
    }
}

实例4:模块间通信 - 地图导航与角色移动

csharp 复制代码
public interface INavigationRequestor
{
    void RequestMove(Vector3 destination);
}

public class CharacterController : MonoBehaviour, INavigationRequestor
{
    private NavigationMediator _mediator;

    public void SetNavigationMediator(NavigationMediator mediator)
    {
        _mediator = mediator;
    }

    public void MoveToTargetPosition(Vector3 position)
    {
        _mediator.RequestMove(position);
    }
}

public class NavigationMediator
{
    private IAstarPathFinder _pathFinder;

    public void RegisterPathFinder(IAstarPathFinder pathFinder)
    {
        _pathFinder = pathFinder;
    }

    public void RequestMove(Vector3 destination)
    {
        var path = _pathFinder.FindPath(transform.position, destination);
        // 处理路径规划结果,并通知CharacterController开始移动
    }
}

public interface IAstarPathFinder
{
    List<Vector3> FindPath(Vector3 start, Vector3 end);
}

实例5:UI模块间同步 - 菜单切换与选项状态

csharp 复制代码
public interface IMenuComponent
{
    void EnableMenu();
    void DisableMenu();
    void NotifyOptionChanged(string optionName, object newValue);
}

public class MainMenu : MonoBehaviour, IMenuComponent
{
    private MenuMediator _mediator;

    public void SetMediator(MenuMediator mediator)
    {
        _mediator = mediator;
    }

    public void OnSettingsButtonClicked()
    {
        _mediator.ToggleMenuToShow(SettingsMenu.instance);
    }

    // 实现菜单启用、禁用以及选项更改的通知方法
}

public class SettingsMenu : MonoBehaviour, IMenuComponent
{
    // 实现菜单组件接口的方法
    // ...

    public void OnResolutionChange(int width, int height)
    {
        Screen.SetResolution(width, height, true);
        _mediator.NotifyOptionChanged("Resolution", new Resolution(width, height));
    }
}

public class MenuMediator
{
    private IMenuComponent _currentActiveMenu;

    public void RegisterMenu(IMenuComponent menu)
    {
        if (_currentActiveMenu == null)
            ActivateMenu(menu);
    }

    public void ToggleMenuToShow(IMenuComponent newMenu)
    {
        DeactivateCurrentMenu();
        ActivateMenu(newMenu);
    }

    private void ActivateMenu(IMenuComponent menu)
    {
        _currentActiveMenu = menu;
        _currentActiveMenu.EnableMenu();
    }

    private void DeactivateCurrentMenu()
    {
        if (_currentActiveMenu != null)
        {
            _currentActiveMenu.DisableMenu();
            _currentActiveMenu = null;
        }
    }

    public void NotifyOptionChanged(string optionName, object newValue)
    {
        // 根据optionName更新所有关联菜单的状态或其他模块响应选项更改
    }
}

以上每个例子都展示了中介者模式如何在不同场景下作为沟通桥梁,减少直接依赖,简化了各个模块之间的交互逻辑。

python推荐学习汇总连接:
50个开发必备的Python经典脚本(1-10)

50个开发必备的Python经典脚本(11-20)

50个开发必备的Python经典脚本(21-30)

50个开发必备的Python经典脚本(31-40)

50个开发必备的Python经典脚本(41-50)


​最后我们放松一下眼睛

相关推荐
张晓~183399481214 小时前
短视频矩阵源码-视频剪辑+AI智能体开发接入技术分享
c语言·c++·人工智能·矩阵·c#·php·音视频
lrh30256 小时前
Custom SRP - Point and Spot Lights
unity·srp·render pipeline
almighty276 小时前
C# DataGridView表头自定义设置全攻略
数据库·c#·winform·datagridview·自定义表头
绀目澄清6 小时前
unity UGUI 鼠标画线
unity·计算机外设·游戏引擎
作孽就得先起床7 小时前
unity pcd 二进制版 简单显示文件对象(单色)
unity·游戏引擎
arbboter8 小时前
【自动化】深入浅出UIAutomationClient:C#桌面自动化实战指南
运维·c#·自动化·inspect·uiautomation·uia·桌面自动化
文弱书生6569 小时前
5.后台运行设置和包设计与实现
服务器·开发语言·c#
大飞pkz12 小时前
【设计模式】题目小练2
开发语言·设计模式·c#·题目小练
csdn_aspnet14 小时前
MongoDB C# .NetCore 驱动程序 序列化忽略属性
mongodb·c#·.netcore
浪扼飞舟14 小时前
c#基础二(类和对象,构造器调用顺序、访问级别、重写和多态、抽象类和接口)
java·开发语言·c#