文章目录
- 示例1:游戏事件处理系统
- 示例2:UI消息处理链
- 示例3:游戏内物理碰撞响应链
- 示例4:AI决策链
- 示例5:场景切换责任链
- 示例6:输入命令处理链
责任链模式(Chain of Responsibility)在Unity中可用于处理一系列可能的请求,通过创建一个对象链来传递这些请求,每个对象都有机会处理它。下面给出5个基于Unity环境下的责任链模式的代码示例:
示例1:游戏事件处理系统
// 基础事件处理器接口
public interface IGameEventHandler
{void HandleEvent(GameEvent gameEvent);IGameEventHandler NextHandler { get; set; }
}// 具体事件处理器类
public class PlayerMoveEventHandler : IGameEventHandler
{public IGameEventHandler NextHandler { get; set; }public void HandleEvent(GameEvent gameEvent){if (gameEvent is MoveEvent moveEvent && moveEvent.Target is Player){// 处理玩家移动事件Debug.Log("Player moved.");if (NextHandler != null) NextHandler.HandleEvent(gameEvent); // 如果有下一个处理器则继续传递}}
}public class EnemyMoveEventHandler : IGameEventHandler
{public IGameEventHandler NextHandler { get; set; }public void HandleEvent(GameEvent gameEvent){if (gameEvent is MoveEvent moveEvent && moveEvent.Target is Enemy){// 处理敌人移动事件Debug.Log("Enemy moved.");if (NextHandler != null) NextHandler.HandleEvent(gameEvent); // 如果有下一个处理器则继续传递}}
}// 构建和使用链
public class GameEventManager
{private IGameEventHandler _headHandler;public GameEventManager(){var playerMoveHandler = new PlayerMoveEventHandler();var enemyMoveHandler = new EnemyMoveEventHandler();playerMoveHandler.NextHandler = enemyMoveHandler;_headHandler = playerMoveHandler;}public void DispatchEvent(GameEvent gameEvent){_headHandler.HandleEvent(gameEvent);}
}// 游戏事件定义
public abstract class GameEvent { }
public class MoveEvent : GameEvent
{public GameObject Target { get; set; }// 其他相关属性...
}// 使用示例
var manager = new GameEventManager();
var moveEvent = new MoveEvent() { Target = /* 某个游戏对象 */ };
manager.DispatchEvent(moveEvent);
示例2:UI消息处理链
// UI消息处理器接口
public interface IMessageHandler
{bool CanHandleMessage(UIEvent message);void HandleMessage(UIEvent message);IMessageHandler NextHandler { get; set; }
}// 具体消息处理器类
public class ButtonClickHandler : IMessageHandler
{public IMessageHandler NextHandler { get; set; }public bool CanHandleMessage(UIEvent message){return message is ButtonClickEvent;}public void HandleMessage(UIEvent message){if (message is ButtonClickEvent clickEvent){Debug.Log($"Button clicked: {clickEvent.ButtonName}");if (NextHandler != null && !NextHandler.CanHandleMessage(message)){NextHandler.HandleMessage(message);}}}
}public class TextInputHandler : IMessageHandler
{// 同样的结构,处理文本输入事件// ...
}// 构建和使用链
public class UIManager
{private IMessageHandler _headHandler;public UIManager(){var buttonHandler = new ButtonClickHandler();var textInputHandler = new TextInputHandler();buttonHandler.NextHandler = textInputHandler;_headHandler = buttonHandler;}public void SendMessage(UIEvent message){if (_headHandler.CanHandleMessage(message)){_headHandler.HandleMessage(message);}else{Debug.LogWarning("No handler for this message.");}}
}// UI事件定义
public abstract class UIEvent {}
public class ButtonClickEvent : UIEvent
{public string ButtonName { get; set; }
}
public class TextInputEvent : UIEvent
{public string Text { get; set; }// ...
}// 使用示例
var uiManager = new UIManager();
var clickEvent = new ButtonClickEvent() { ButtonName = "Start" };
uiManager.SendMessage(clickEvent);
示例3:游戏内物理碰撞响应链
// 碰撞处理器接口
public interface ICollisionHandler
{bool ShouldHandleCollision(Collision collision);void OnCollisionEnter(Collision collision);ICollisionHandler NextHandler { get; set; }
}// 具体碰撞处理器类
public class HealthPickupCollisionHandler : ICollisionHandler
{public ICollisionHandler NextHandler { get; set; }public bool ShouldHandleCollision(Collision collision){return collision.gameObject.CompareTag("Player") && collision.gameObject.TryGetComponent(out HealthComponent health);}public void OnCollisionEnter(Collision collision){if (ShouldHandleCollision(collision)){var health = collision.gameObject.GetComponent<HealthComponent>();health.Restore(10); // 恢复生命值if (NextHandler != null){NextHandler.OnCollisionEnter(collision);}}}
}public class ScorePickupCollisionHandler : ICollisionHandler
{// 类似地处理得分拾取事件// ...
}// 构建和使用链
public class CollisionManager : MonoBehaviour
{public ICollisionHandler HeadHandler;void OnCollisionEnter(Collision collision){HeadHandler?.OnCollisionEnter(collision);}
}// 使用示例
public class GameManager : MonoBehaviour
{void Start(){var healthPickupHandler = new HealthPickupCollisionHandler();var scorePickupHandler = new ScorePickupCollisionHandler();healthPickupHandler.NextHandler = scorePickupHandler;GetComponent<CollisionManager>().HeadHandler = healthPickupHandler;}
}
示例4:AI决策链
// AI决策器接口
public interface IAIDecisionMaker
{bool Decide(GameObject agent, List<WorldState> worldStates);IAIDecisionMaker NextDecisionMaker { get; set; }
}// 具体决策器类
public class FleeFromDangerDecisionMaker : IAIDecisionMaker
{public IAIDecisionMaker NextDecisionMaker { get; set; }public bool Decide(GameObject agent, List<WorldState> worldStates){var inDanger = worldStates.Any(s => s.IsDangerNearby);if (inDanger){// 逃离危险逻辑Debug.Log($"{agent.name} flees from danger.");return true; // 已作出决定,不需后续决策器处理}else if (NextDecisionMaker != null){return NextDecisionMaker.Decide(agent, worldStates);}return false;}
}public class FindResourceDecisionMaker : IAIDecisionMaker
{// 寻找资源的逻辑// ...
}// 构建和使用链
public class AIThinkingManager
{public IAIDecisionMaker DecisionChain;public void MakeDecision(GameObject agent, List<WorldState> worldStates){if (DecisionChain.Decide(agent, worldStates)){// 执行相应的动作}}
}// 使用示例
public class AIController : MonoBehaviour
{void Start(){var fleeDecisionMaker = new FleeFromDangerDecisionMaker();var findResourceDecisionMaker = new FindResourceDecisionMaker();fleeDecisionMaker.NextDecisionMaker = findResourceDecisionMaker;var aiThinkingManager = new AIThinkingManager();aiThinkingManager.DecisionChain = fleeDecisionMaker;}
}// 世界状态定义
public class WorldState { ... }
示例5:场景切换责任链
// 场景切换处理器接口
public interface ISceneTransitionHandler
{bool CanTransitionTo(Scene scene);void TransitionTo(Scene scene);ISceneTransitionHandler NextHandler { get; set; }
}// 具体场景切换处理器类
public class LoadMainMenuTransitionHandler : ISceneTransitionHandler
{public ISceneTransitionHandler NextHandler { get; set; }public bool CanTransitionTo(Scene scene){return scene.name == "MainMenu";}public void TransitionTo(Scene scene){SceneManager.LoadScene(scene.name);if (NextHandler != null && !NextHandler.CanTransitionTo(scene)){NextHandler.TransitionTo(scene);}}
}public class QuitApplicationTransitionHandler : ISceneTransitionHandler
{// 处理退出应用的逻辑// ...
}// 构建和使用链
public class SceneTransitionManager
{private ISceneTransitionHandler _headHandler;public SceneTransitionManager(ISceneTransitionHandler firstHandler){_headHandler = firstHandler;}public void TryTransitionTo(Scene scene){_headHandler.TransitionTo(scene);}
}// 使用示例
public class GameManager : MonoBehaviour
{void Start(){var mainMenuHandler = new LoadMainMenuTransitionHandler();var quitHandler = new QuitApplicationTransitionHandler();mainMenuHandler.NextHandler = quitHandler;var transitionManager = new SceneTransitionManager(mainMenuHandler);// 当需要切换到特定场景时调用
public void OnMainMenuButtonClicked()
{var mainMenuScene = SceneManager.GetSceneByName("MainMenu");transitionManager.TryTransitionTo(mainMenuScene);
}public void OnQuitButtonClicked()
{var quitScene = new Scene { name = "Quit" }; // 假设有一个表示退出的场景transitionManager.TryTransitionTo(quitScene);
}TryTransitionTo 方法```csharp
public void OnMainMenuButtonClicked()
{var mainMenuScene = SceneManager.GetSceneByName("MainMenu");transitionManager.TryTransitionTo(mainMenuScene);
}public void OnQuitButtonClicked()
{var quitScene = new Scene { name = "Quit" }; // 假设有一个表示退出的场景transitionManager.TryTransitionTo(quitScene);
}
示例6:输入命令处理链
// 输入命令处理器接口
public interface ICommandHandler
{bool CanHandleCommand(string command);void HandleCommand(string command);ICommandHandler NextHandler { get; set; }
}// 具体命令处理器类
public class MovePlayerCommandHandler : ICommandHandler
{public ICommandHandler NextHandler { get; set; }public bool CanHandleCommand(string command){return command.StartsWith("move player ");}public void HandleCommand(string command){var direction = command.Substring("move player ".Length);// 根据direction移动玩家Debug.Log($"Player moved to {direction}.");if (NextHandler != null && !NextHandler.CanHandleCommand(command)){NextHandler.HandleCommand(command);}}
}public class OpenDoorCommandHandler : ICommandHandler
{// 处理打开门的命令逻辑// ...
}// 构建和使用链
public class CommandDispatcher
{private ICommandHandler _headHandler;public CommandDispatcher(ICommandHandler firstHandler){_headHandler = firstHandler;}public void DispatchCommand(string command){_headHandler.HandleCommand(command);}
}// 使用示例
public class GameInputController : MonoBehaviour
{private CommandDispatcher _dispatcher;void Start(){var movePlayerHandler = new MovePlayerCommandHandler();var openDoorHandler = new OpenDoorCommandHandler();movePlayerHandler.NextHandler = openDoorHandler;_dispatcher = new CommandDispatcher(movePlayerHandler);}public void OnUserInput(string command){_dispatcher.DispatchCommand(command);}
}// 使用示例
_gameInputController.OnUserInput("move player north"); // 移动玩家到北方
_gameInputController.OnUserInput("open door west"); // 打开西边的门
以上六个示例展示了责任链模式在Unity中的应用,通过构建一系列处理器对象并按照特定条件传递请求或事件,使得每个处理器都有机会执行相应的操作,并且可以根据需要灵活地添加、删除或修改链中的处理器。
python推荐学习汇总连接:
50个开发必备的Python经典脚本(1-10)
50个开发必备的Python经典脚本(11-20)
50个开发必备的Python经典脚本(21-30)
50个开发必备的Python经典脚本(31-40)
50个开发必备的Python经典脚本(41-50)
————————————————
最后我们放松一下眼睛