文章目录
责任链模式(Chain of Responsibility)在Unity中可用于处理一系列可能的请求,通过创建一个对象链来传递这些请求,每个对象都有机会处理它。下面给出5个基于Unity环境下的责任链模式的代码示例:
示例1:游戏事件处理系统
csharp
// 基础事件处理器接口
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消息处理链
csharp
// 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:游戏内物理碰撞响应链
csharp
// 碰撞处理器接口
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决策链
csharp
// 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:场景切换责任链
csharp
// 场景切换处理器接口
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:输入命令处理链
csharp
// 输入命令处理器接口
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)
最后我们放松一下眼睛