——以Unity实现标准化游戏流程与灵活AI行为框架为核心案例
核心目标:
✅ 定义算法骨架,将某些步骤延迟到子类实现
✅ 复用算法结构,确保流程一致性
✅ 避免代码冗余,通过继承实现差异化
关键术语:
数学表达:
设算法流程为:A → B → C → D
模板方法确保所有子类遵循此流程,但允许自定义B和C的实现
public abstract class GameLevel : MonoBehaviour {
// 模板方法(不可重写)
public sealed override IEnumerator PlayLevel() {
LoadLevelAssets();
yield return InitializeLevel();
yield return StartLevelCore();
yield return EndLevelProcess();
Cleanup();
}
// 具体步骤(部分有默认实现)
protected virtual void LoadLevelAssets() {
Debug.Log("加载基础资源...");
// 加载公共资源逻辑
}
protected abstract IEnumerator InitializeLevel();
protected abstract IEnumerator StartLevelCore();
protected virtual IEnumerator EndLevelProcess() {
Debug.Log("执行默认结算流程...");
yield return new WaitForSeconds(1);
}
protected virtual void Cleanup() {
Debug.Log("清理临时资源...");
}
}
// BOSS关卡
public class BossLevel : GameLevel {
[SerializeField] private GameObject _bossPrefab;
protected override IEnumerator InitializeLevel() {
Debug.Log("生成BOSS...");
Instantiate(_bossPrefab);
yield return new WaitForSeconds(2);
}
protected override IEnumerator StartLevelCore() {
Debug.Log("开始BOSS战!");
// BOSS战斗逻辑
yield return new WaitUntil(() => !IsBossAlive());
}
private bool IsBossAlive() {
// 检测BOSS存活状态
return true;
}
}
// 解谜关卡
public class PuzzleLevel : GameLevel {
[SerializeField] private PuzzleSystem _puzzle;
protected override IEnumerator InitializeLevel() {
Debug.Log("初始化谜题组件...");
_puzzle.ResetPuzzle();
yield return null;
}
protected override IEnumerator StartLevelCore() {
Debug.Log("启动谜题...");
yield return new WaitUntil(() => _puzzle.IsSolved);
}
protected override IEnumerator EndLevelProcess() {
yield return base.EndLevelProcess();
Debug.Log("展示解谜奖励...");
yield return new WaitForSeconds(2);
}
}
public class LevelManager : MonoBehaviour {
[SerializeField] private GameLevel _currentLevel;
void Start() {
StartCoroutine(PlayCurrentLevel());
}
private IEnumerator PlayCurrentLevel() {
yield return _currentLevel.PlayLevel();
Debug.Log("关卡流程结束!");
}
public void SwitchLevel(GameLevel newLevel) {
_currentLevel = newLevel;
StartCoroutine(PlayCurrentLevel());
}
}
protected virtual bool ShouldSkipIntro() => false;
public sealed override IEnumerator PlayLevel() {
if(!ShouldSkipIntro()) {
yield return PlayIntroAnimation();
}
// 后续流程...
}
public abstract class GameLevel : MonoBehaviour {
private enum LevelState { Loading, Initializing, Running, Ending }
private LevelState _currentState;
protected void SetState(LevelState newState) {
_currentState = newState;
OnStateChanged?.Invoke(newState);
}
public event Action<LevelState> OnStateChanged;
}
protected virtual async Task LoadLevelAssetsAsync() {
var loadOp = Addressables.LoadAssetsAsync<GameObject>("LevelBaseAssets");
await loadOp.Task;
Debug.Log($"已加载 {loadOp.Result.Count} 个基础资源");
}
角色行为模板
public abstract class CharacterBehavior {
public void ExecuteDailyRoutine() {
WakeUp();
Eat();
Work();
Sleep();
}
protected abstract void Work();
// 其他步骤可有默认实现...
}
技能释放流程
public abstract class SkillBase {
public void Cast() {
PlayCastAnimation();
ApplyPreEffects();
ExecuteCoreLogic();
ApplyPostEffects();
}
protected abstract void ExecuteCoreLogic();
}
UI面板通用流程
public abstract class UIPanel : MonoBehaviour {
public IEnumerator Show() {
PreShowSetup();
yield return PlayShowAnimation();
PostShowInitialize();
}
protected virtual void PreShowSetup() { /* 默认空实现 */ }
protected abstract IEnumerator PlayShowAnimation();
}
敌人生成系统
public abstract class EnemySpawner {
public void SpawnWave() {
PreSpawnCheck();
CalculateSpawnPoints();
SpawnEnemies();
PostSpawnActions();
}
protected abstract void SpawnEnemies();
}
策略 | 实现方式 | 适用场景 |
---|---|---|
预编译模板 | 使用泛型模板类 | 高频实例化场景 |
步骤缓存 | 缓存重复计算结果 | 复杂初始化流程 |
分帧执行 | 使用协程分步骤执行 | 长耗时流程 |
资源预加载 | 提前加载共用资源 | 资源密集型关卡 |
维度 | 模板方法模式 | 策略模式 |
---|---|---|
代码复用方式 | 继承 | 组合 |
灵活性 | 修改需要继承 | 运行时动态切换 |
适用场景 | 固定流程算法 | 可替换算法模块 |
扩展方向 | 垂直扩展(子类化) | 水平扩展(新增策略) |
public sealed override void ExecuteProcess() { /* ... */ }
///
/// 初始化关卡核心元素,必须由子类实现
///
protected abstract void InitializeCore();
Q1:如何避免过度继承?
→ 使用组合+模板方法混合模式
public class LevelProcessor {
private ILevelInitializer _initializer;
private ILevelFinalizer _finalizer;
public void ExecuteProcess() {
LoadCommonAssets();
_initializer.Initialize();
RunCoreLogic();
_finalizer.Finalize();
}
}
Q2:如何处理跨步骤状态共享?
→ 使用上下文对象传递数据
public class LevelContext {
public int Score;
public float TimeSpent;
public List<Enemy> AliveEnemies = new();
}
protected abstract void ExecuteCore(LevelContext context);
Q3:如何调试多层级模板?
→ 实现步骤追踪器
public abstract class DebuggableTemplate : MonoBehaviour {
private void LogStep(string message) {
Debug.Log($"[{Time.time:F2}] {GetType().Name} - {message}");
}
protected sealed override void LoadResources() {
LogStep("开始加载资源");
base.LoadResources();
LogStep("资源加载完成");
}
}
上一篇 【行为型之策略模式】游戏开发实战——Unity灵活算法架构的核心实现策略
下一篇 【行为型之访问者模式】游戏开发实战——Unity灵活数据操作与跨系统交互的架构秘诀