Game_Num_Basics_And_Calc

🏗️ 游戏设计模式:理论与 Unity 实战

设计模式 (Design Patterns) 是解决常见架构问题的通用方案。但在游戏开发中,性能敏感性和迭代速度要求我们对经典模式进行“魔改”。

本文档总结了在 Project Vampirefall 及业界 3A/独立游戏中最高频使用的模式。


1. 核心模式 (The Essentials)

1.1 单例模式 (Singleton) & 服务定位器 (Service Locator)

1.2 对象池模式 (Object Pool)

1.3 状态机模式 (State Machine / FSM)


2. 进阶架构模式 (Advanced Architecture)

2.1 观察者模式 (Observer / Event Bus)

2.2 命令模式 (Command)

2.3 装饰器模式 (Decorator) - Deep Dive

A. 为什么“继承”是死胡同?

假设你需要实现:A(火焰)、B(冰冻)、C(吸血)。 如果用继承:FireAttack, IceAttack, FireAndIceAttack组合爆炸 (Combinatorial Explosion): 10 种效果需要 $2^{10} = 1024$ 个类。

B. 像俄罗斯套娃一样 (The “Russian Doll” Model)

装饰器模式创建的是“包装纸”。

  1. Component (接口): IAttack
  2. Concrete (本体): SwordAttack (最里面的娃娃)
  3. Decorator (包装): FireDecorator (包在外面)

调用链: Game -> LifeSteal -> Fire -> Sword

C. Vampirefall 实战代码 (C#)

// 1. 接口
public interface IAttack {
    void Execute(Enemy target, DamageInfo info);
}

// 2. 本体
public class SwordAttack : IAttack {
    public void Execute(Enemy target, DamageInfo info) {
        target.TakeDamage(info.BaseDamage); // 核心逻辑
    }
}

// 3. 装饰器基类
public abstract class AttackDecorator : IAttack {
    protected IAttack _inner;
    public AttackDecorator(IAttack inner) { _inner = inner; }
    public virtual void Execute(Enemy target, DamageInfo info) {
        _inner.Execute(target, info); // 转发
    }
}

// 4. 具体装饰器:拦截与修改
public class CritDecorator : AttackDecorator {
    public CritDecorator(IAttack inner) : base(inner) {}
    public override void Execute(Enemy target, DamageInfo info) {
        // 拦截输入:在攻击发生前修改参数
        if (Random.value < 0.2f) info.BaseDamage *= 2.0f; 
        base.Execute(target, info);
    }
}

D. 装饰器 vs 事件 (Event)

E. 工业级痛点与进化:管道模式 (Pipeline)

标准的 GoF 装饰器在面对复杂 RPG 系统时有三大缺陷:

  1. 移除困难: 想要移除中间的一层包装(如 Buff 过期),需要解构整个链条。
  2. 顺序混乱: 先加后乘 (10+5)*1.5 vs 先乘后加 (10*1.5)+5,结果截然不同。
  3. 互斥管理: 如何实现“武器附魔只能有一个”?

解决方案:Modifier Pipeline (中间件模式) 不再使用层层包裹,而是维护一个有序列表

public enum ModifierPriority {
    BaseStats = 100,   // 基础数值 (+10)
    Multiplier = 200,  // 乘法修正 (+50%)
    Conversion = 300,  // 属性转化 (物理转火)
    OnHit = 400        // 击中特效
}

public class AttackPipeline {
    private List<IAttackModifier> _modifiers = new List<IAttackModifier>();

    public void AddModifier(IAttackModifier mod) {
        // 1. 处理互斥 (Conflict Policy)
        var existing = _modifiers.Find(m => m.GroupID == mod.GroupID);
        if (existing != null && mod.Policy == ConflictPolicy.Override) {
            _modifiers.Remove(existing);
        }
        
        // 2. 添加并排序
        _modifiers.Add(mod);
        _modifiers.Sort((a, b) => a.Priority.CompareTo(b.Priority));
    }

    public void Execute(AttackContext ctx) {
        foreach (var mod in _modifiers) {
            mod.OnAttack(ctx);
            if (ctx.IsConsumed) break; // 支持中断 (如被格挡)
        }
    }
}

3. 性能特化模式 (Performance Oriented)

3.1 数据局部性 (Data Locality / ECS)

3.2 享元模式 (Flyweight)


4. 设计模式陷阱 (Anti-Patterns)

  1. 过度单例 (Singleton Abuse): 导致代码变成一团乱麻,哪里都能改数据,无法追踪 Bug 来源。
  2. 上帝类 (God Class): 一个 PlayerController 写了 3000 行代码,包含输入、移动、动画、音效。解法: 使用组件模式 (Component),拆分为 PlayerInput, PlayerMover, PlayerAnimator
  3. 过度设计 (Over-Engineering): 为还没出现的需求写复杂的接口。YAGNI (You Aren’t Gonna Need It) 原则是王道。

📚 扩展阅读与代码圣经 (References)

🏛️ 设计模式基础

🏎️ 性能与架构

🔧 实战案例