文章目录
- 简介
- 实例1:玩家与UI交互
- 实例2:战斗模块中的攻击事件协调
- 实例3:游戏场景中的事件广播
- 实例4:模块间通信 - 地图导航与角色移动
- 实例5:UI模块间同步 - 菜单切换与选项状态
简介
在Unity游戏开发中,中介者(Mediator)模式用于降低多个对象之间的耦合度,通过引入一个中介类来封装和管理对象间的交互。下面我将提供五个简化的代码实例来说明如何在Unity项目中应用中介者模式:
实例1:玩家与UI交互
// 定义用户界面组件接口
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:战斗模块中的攻击事件协调
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:游戏场景中的事件广播
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:模块间通信 - 地图导航与角色移动
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模块间同步 - 菜单切换与选项状态
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)
————————————————
最后我们放松一下眼睛