责任链模式 = 一件事,按顺序问一串"人",谁能处理谁就处理,处理不了就交给下一个
重点只有两个:
-
请求只发一次
-
具体谁处理,请求自己往后传
比如你想请假一天:
-
组长
-
1 天以内 👉 我批了
-
超过 1 天 👉 我没权限,往上交
-
-
主管
-
3 天以内 👉 我批了
-
超过 3 天 👉 再往上交
-
-
老板
- 任何天数 👉 我说了算
1.责任链基类
责任链基类定义了下一个处理类和抽象处理方法。
cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// 伤害处理基类
public abstract class DamageHandler
{
protected DamageHandler next;
public void SetNext(DamageHandler nextHandler)
{
next = nextHandler;
}
public abstract void Handle(ref int damage);
}
2.具体责任方法
闪避处理器,闪避率百分之50。
cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// 闪避处理器
public class DodgeHandler : DamageHandler
{
public override void Handle(ref int damage)
{
if (Random.value < 0.5f)
{
Debug.Log("闪避成功,0伤害");
damage = 0;
return; // 责任到我为止
}
next?.Handle(ref damage);
}
}
护盾处理器
cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//护盾处理器
public class ShieldHandler : DamageHandler
{
int shield = 50;
public override void Handle(ref int damage)
{
if (shield > 0)
{
int absorb = Mathf.Min(shield, damage);
shield -= absorb;//护盾值减少
damage -= absorb;//伤害减少
Debug.Log("护盾吸收伤害"+absorb +"护盾剩余"+ shield);
if (damage <= 0) return;//伤害减完了直接返回
}
next?.Handle(ref damage);
}
}
最终的血量消耗处理器
cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//血量消耗处理器
public class HpHandler : DamageHandler
{
public override void Handle(ref int damage)
{
Debug.Log($"最终扣血:{damage}");
}
}
3.使用
当用户按下空格键的时候就会模拟一次伤害,并按照事先设定的责任链执行对应的方法。
cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
//责任链入口
DamageHandler dodge;
void Start()
{
dodge = new DodgeHandler();
DamageHandler shield = new ShieldHandler();
DamageHandler hp = new HpHandler();
//创建责任链
dodge.SetNext(shield);
shield.SetNext(hp);
//处理流程 闪避 ->护盾->伤害
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Understriking();
}
}
//模拟受伤
void Understriking()
{
int damage = Random.Range(1, 100);
Debug.Log("原始伤害"+damage);
dodge.Handle(ref damage);
}
}
4.运行
将Player脚本加到场景中的一个空对象上然后运行游戏按下空格,可以看到一些列的伤害处理过程被打印了出来,并且护盾扣完过后并就无法提供多余的减伤了,符合游戏逻辑。

5.总结
通过这个示例可以看到,责任链模式的核心思想并不复杂:
将一个复杂的处理流程拆分成多个独立的步骤,并通过链式结构按顺序执行。
在伤害系统中,每个处理器只负责一件事:
闪避只关心能不能躲,护盾只关心能吸多少,血量只关心最终扣多少。
当规则发生变化时,我们无需修改原有代码,只需要调整责任链的组合顺序,甚至动态插入新的处理器,就可以完成需求扩展。