【Unity设计模式】Unity中常用的设计模式

ModelEngine·创作计划征文活动 10w+人浏览 1.5k人参与

Unity中常用的设计模式

🎨 创建型模式(Creational Patterns)

1. 单例模式(Singleton) ⭐⭐⭐⭐⭐

Unity中最常用的模式

// A. 普通C#单例
public class GameManager {
    private static GameManager instance;
    private static readonly object lockObj = new object();
    
    public static GameManager Instance {
        get {
            if (instance == null) {
                lock (lockObj) {
                    if (instance == null) {
                        instance = new GameManager();
                    }
                }
            }
            return instance;
        }
    }
    
    private GameManager() {
        // 私有构造函数
    }
}

// B. MonoBehaviour单例(最常用)
public class MonoSingleton<T> : MonoBehaviour where T : MonoBehaviour {
    private static T instance;
    private static object lockObj = new object();
    
    public static T Instance {
        get {
            if (instance == null) {
                lock (lockObj) {
                    if (instance == null) {
                        instance = FindObjectOfType<T>();
                        
                        if (instance == null) {
                            GameObject singleton = new GameObject($"[Singleton]{typeof(T)}");
                            instance = singleton.AddComponent<T>();
                            DontDestroyOnLoad(singleton);
                        }
                    }
                }
            }
            return instance;
        }
    }
    
    protected virtual void Awake() {
        if (instance == null) {
            instance = this as T;
            DontDestroyOnLoad(gameObject);
        } else if (instance != this) {
            Destroy(gameObject);
        }
    }
}

// 使用
public class AudioManager : MonoSingleton<AudioManager> {
    public void PlaySound(string soundName) {
        Debug.Log($"播放音效: {soundName}");
    }
}

// 调用
AudioManager.Instance.PlaySound("explosion");

// C. 懒汉式单例(线程安全)
public sealed class LazyGameManager {
    private static readonly Lazy<LazyGameManager> lazy = 
        new Lazy<LazyGameManager>(() => new LazyGameManager());
    
    public static LazyGameManager Instance => lazy.Value;
    
    private LazyGameManager() { }
}

应用场景:

  • 游戏管理器(GameManager)
  • 音频管理器(AudioManager)
  • UI管理器(UIManager)
  • 资源管理器(ResourceManager)

2. 工厂模式(Factory) ⭐⭐⭐⭐⭐
// A. 简单工厂
public enum EnemyType {
    Zombie,
    Skeleton,
    Boss
}

public class EnemyFactory {
    public Enemy CreateEnemy(EnemyType type) {
        switch (type) {
            case EnemyType.Zombie:
                return new Zombie();
            case EnemyType.Skeleton:
                return new Skeleton();
            case EnemyType.Boss:
                return new Boss();
            default:
                return null;
        }
    }
}

// B. 工厂方法(更灵活)
public abstract class Enemy : MonoBehaviour {
    public abstract void Attack();
}

public class Zombie : Enemy {
    public override void Attack() {
        Debug.Log("僵尸攻击");
    }
}

public abstract class EnemySpawner : MonoBehaviour {
    public abstract Enemy CreateEnemy();
    
    public Enemy SpawnEnemy(Vector3 position) {
        Enemy enemy = CreateEnemy();
        enemy.transform.position = position;
        return enemy;
    }
}

public class ZombieSpawner : EnemySpawner {
    public GameObject zombiePrefab;
    
    public override Enemy CreateEnemy() {
        GameObject obj = Instantiate(zombiePrefab);
        return obj.GetComponent<Zombie>();
    }
}

// C. 抽象工厂(创建产品族)
public interface IUIFactory {
    IButton CreateButton();
    IPanel CreatePanel();
    ISlider CreateSlider();
}

public class ModernUIFactory : IUIFactory {
    public IButton CreateButton() => new ModernButton();
    public IPanel CreatePanel() => new ModernPanel();
    public ISlider CreateSlider() => new ModernSlider();
}

public class ClassicUIFactory : IUIFactory {
    public IButton CreateButton() => new ClassicButton();
    public IPanel CreatePanel() => new ClassicPanel();
    public ISlider CreateSlider() => new ClassicSlider();
}

// 使用
public class UIManager : MonoBehaviour {
    private IUIFactory uiFactory;
    
    void Start() {
        // 根据配置选择UI风格
        if (GameSettings.UIStyle == "Modern") {
            uiFactory = new ModernUIFactory();
        } else {
            uiFactory = new ClassicUIFactory();
        }
        
        // 创建UI组件(统一风格)
        IButton btn = uiFactory.CreateButton();
        IPanel panel = uiFactory.CreatePanel();
    }
}

应用场景:

  • 敌人生成系统
  • UI组件创建
  • 道具/装备生成
  • 关卡元素生成

3. 对象池模式(Object Pool) ⭐⭐⭐⭐⭐
// Unity中性能优化必备
public class ObjectPool<T> where T : Component {
    private Queue<T> pool;
    private T prefab;
    private Transform parent;
    
    public ObjectPool(T prefab, int initialSize = 10, Transform parent = null) {
        this.prefab = prefab;
        this.parent = parent;
        this.pool = new Queue<T>();
        
        // 预创建对象
        for (int i = 0; i < initialSize; i++) {
            T obj = Object.Instantiate(prefab, parent);
            obj.gameObject.SetActive(false);
            pool.Enqueue(obj);
        }
    }
    
    public T Get() {
        T obj;
        
        if (pool.Count > 0) {
            obj = pool.Dequeue();
            obj.gameObject.SetActive(true);
        } else {
            obj = Object.Instantiate(prefab, parent);
        }
        
        return obj;
    }
    
    public void Return(T obj) {
        obj.gameObject.SetActive(false);
        pool.Enqueue(obj);
    }
    
    public void Clear() {
        while (pool.Count > 0) {
            Object.Destroy(pool.Dequeue().gameObject);
        }
    }
}

// 使用示例
public class BulletManager : MonoBehaviour {
    public Bullet bulletPrefab;
    private ObjectPool<Bullet> bulletPool;
    
    void Start() {
        bulletPool = new ObjectPool<Bullet>(bulletPrefab, 50, transform);
    }
    
    public void Fire(Vector3 position, Vector3 direction) {
        Bullet bullet = bulletPool.Get();
        bullet.transform.position = position;
        bullet.Fire(direction);
        
        // 3秒后回收
        StartCoroutine(ReturnBulletAfterDelay(bullet, 3f));
    }
    
    IEnumerator ReturnBulletAfterDelay(Bullet bullet, float delay) {
        yield return new WaitForSeconds(delay);
        bulletPool.Return(bullet);
    }
}

// Unity官方的对象池(2021+)
using UnityEngine.Pool;

public class ModernBulletManager : MonoBehaviour {
    public Bullet bulletPrefab;
    private ObjectPool<Bullet> bulletPool;
    
    void Start() {
        bulletPool = new ObjectPool<Bullet>(
            createFunc: () => Instantiate(bulletPrefab),
            actionOnGet: bullet => bullet.gameObject.SetActive(true),
            actionOnRelease: bullet => bullet.gameObject.SetActive(false),
            actionOnDestroy: bullet => Destroy(bullet.gameObject),
            collectionCheck: true,
            defaultCapacity: 50,
            maxSize: 100
        );
    }
    
    public void Fire() {
        Bullet bullet = bulletPool.Get();
        // 使用子弹
        bulletPool.Release(bullet);
    }
}

4. 建造者模式(Builder) ⭐⭐⭐⭐
// 构建复杂对象
public class Character {
    public string Name;
    public int Level;
    public int Health;
    public int Mana;
    public List<string> Skills;
    public Dictionary<string, int> Attributes;
}

public class CharacterBuilder {
    private Character character;
    
    public CharacterBuilder() {
        character = new Character {
            Skills = new List<string>(),
            Attributes = new Dictionary<string, int>()
        };
    }
    
    public CharacterBuilder SetName(string name) {
        character.Name = name;
        return this;
    }
    
    public CharacterBuilder SetLevel(int level) {
        character.Level = level;
        character.Health = level * 100;
        character.Mana = level * 50;
        return this;
    }
    
    public CharacterBuilder AddSkill(string skill) {
        character.Skills.Add(skill);
        return this;
    }
    
    public CharacterBuilder SetAttribute(string attr, int value) {
        character.Attributes[attr] = value;
        return this;
    }
    
    public Character Build() {
        return character;
    }
}

// 使用(链式调用)
Character warrior = new CharacterBuilder()
    .SetName("战士")
    .SetLevel(10)
    .AddSkill("重击")
    .AddSkill("旋风斩")
    .SetAttribute("力量", 50)
    .SetAttribute("体质", 40)
    .Build();

// 更复杂的建造者:武器系统
public class Weapon {
    public string Name;
    public int BaseDamage;
    public float AttackSpeed;
    public List<WeaponMod> Mods;
    public GameObject Model;
    public AudioClip AttackSound;
    public ParticleSystem Effect;
}

public class WeaponBuilder {
    private Weapon weapon = new Weapon { Mods = new List<WeaponMod>() };
    
    public WeaponBuilder SetBase(string name, int damage, float speed) {
        weapon.Name = name;
        weapon.BaseDamage = damage;
        weapon.AttackSpeed = speed;
        return this;
    }
    
    public WeaponBuilder AddMod(WeaponMod mod) {
        weapon.Mods.Add(mod);
        weapon.BaseDamage += mod.DamageBonus;
        return this;
    }
    
    public WeaponBuilder SetVisuals(GameObject model, ParticleSystem effect) {
        weapon.Model = model;
        weapon.Effect = effect;
        return this;
    }
    
    public WeaponBuilder SetAudio(AudioClip sound) {
        weapon.AttackSound = sound;
        return this;
    }
    
    public Weapon Build() => weapon;
}

应用场景:

  • 角色创建
  • 装备/武器配置
  • 关卡生成器
  • UI对话框构建

5. 原型模式(Prototype) ⭐⭐⭐
// 克隆对象
public interface ICloneable<T> {
    T Clone();
}

public class Enemy : MonoBehaviour, ICloneable<Enemy> {
    public string enemyName;
    public int health;
    public int damage;
    public List<string> abilities;
    
    public Enemy Clone() {
        // 深拷贝
        Enemy clone = Instantiate(this);
        clone.abilities = new List<string>(this.abilities);
        return clone;
    }
}

// ScriptableObject作为原型
[CreateAssetMenu(fileName = "EnemyData", menuName = "Game/Enemy")]
public class EnemyData : ScriptableObject {
    public string enemyName;
    public int baseHealth;
    public int baseDamage;
    public GameObject prefab;
    
    // 从原型创建实例
    public Enemy CreateEnemy() {
        GameObject obj = Instantiate(prefab);
        Enemy enemy = obj.GetComponent<Enemy>();
        enemy.enemyName = enemyName;
        enemy.health = baseHealth;
        enemy.damage = baseDamage;
        return enemy;
    }
}

// 使用原型管理器
public class EnemyPrototypeManager : MonoBehaviour {
    private Dictionary<string, EnemyData> prototypes = new Dictionary<string, EnemyData>();
    
    void Start() {
        // 加载所有原型
        EnemyData[] datas = Resources.LoadAll<EnemyData>("Enemies");
        foreach (var data in datas) {
            prototypes[data.enemyName] = data;
        }
    }
    
    public Enemy SpawnEnemy(string enemyName, Vector3 position) {
        if (prototypes.TryGetValue(enemyName, out EnemyData data)) {
            Enemy enemy = data.CreateEnemy();
            enemy.transform.position = position;
            return enemy;
        }
        return null;
    }
}

🏗️ 结构型模式(Structural Patterns)

6. 组合模式(Composite) ⭐⭐⭐⭐
// Unity的Transform天然就是组合模式
// 实现技能组合系统
public abstract class SkillComponent {
    public abstract void Execute();
    public abstract float GetCooldown();
}

// 叶子节点:基础技能
public class BasicSkill : SkillComponent {
    private string skillName;
    private float cooldown;
    
    public BasicSkill(string name, float cd) {
        skillName = name;
        cooldown = cd;
    }
    
    public override void Execute() {
        Debug.Log($"执行技能: {skillName}");
    }
    
    public override float GetCooldown() => cooldown;
}

// 组合节点:技能组合
public class ComboSkill : SkillComponent {
    private List<SkillComponent> skills = new List<SkillComponent>();
    private string comboName;
    
    public ComboSkill(string name) {
        comboName = name;
    }
    
    public void Add(SkillComponent skill) {
        skills.Add(skill);
    }
    
    public void Remove(SkillComponent skill) {
        skills.Remove(skill);
    }
    
    public override void Execute() {
        Debug.Log($"执行连招: {comboName}");
        foreach (var skill in skills) {
            skill.Execute();
        }
    }
    
    public override float GetCooldown() {
        float total = 0;
        foreach (var skill in skills) {
            total += skill.GetCooldown();
        }
        return total;
    }
}

// 使用
ComboSkill ultimateCombo = new ComboSkill("终极连招");
ultimateCombo.Add(new BasicSkill("破甲", 1f));
ultimateCombo.Add(new BasicSkill("重击", 2f));
ultimateCombo.Add(new BasicSkill("终结", 3f));

ultimateCombo.Execute();  // 执行整个连招
float totalCD = ultimateCombo.GetCooldown();  // 总冷却时间

7. 装饰器模式(Decorator) ⭐⭐⭐⭐
// 动态添加功能
public interface IWeapon {
    int GetDamage();
    string GetDescription();
}

public class BasicSword : IWeapon {
    public int GetDamage() => 10;
    public string GetDescription() => "基础剑";
}

// 装饰器基类
public abstract class WeaponDecorator : IWeapon {
    protected IWeapon weapon;
    
    public WeaponDecorator(IWeapon weapon) {
        this.weapon = weapon;
    }
    
    public virtual int GetDamage() => weapon.GetDamage();
    public virtual string GetDescription() => weapon.GetDescription();
}

// 具体装饰器
public class FireEnchantment : WeaponDecorator {
    public FireEnchantment(IWeapon weapon) : base(weapon) { }
    
    public override int GetDamage() => weapon.GetDamage() + 5;
    public override string GetDescription() => weapon.GetDescription() + " + 火焰附魔";
}

public class SharpnessEnchantment : WeaponDecorator {
    public SharpnessEnchantment(IWeapon weapon) : base(weapon) { }
    
    public override int GetDamage() => weapon.GetDamage() + 3;
    public override string GetDescription() => weapon.GetDescription() + " + 锋利";
}

public class CriticalHitMod : WeaponDecorator {
    public CriticalHitMod(IWeapon weapon) : base(weapon) { }
    
    public override int GetDamage() {
        // 20%暴击
        if (UnityEngine.Random.value < 0.2f) {
            return weapon.GetDamage() * 2;
        }
        return weapon.GetDamage();
    }
    
    public override string GetDescription() => weapon.GetDescription() + " + 暴击";
}

// 使用(动态叠加)
IWeapon weapon = new BasicSword();
weapon = new FireEnchantment(weapon);
weapon = new SharpnessEnchantment(weapon);
weapon = new CriticalHitMod(weapon);

Debug.Log(weapon.GetDescription());  // "基础剑 + 火焰附魔 + 锋利 + 暴击"
Debug.Log($"伤害: {weapon.GetDamage()}");  // 18 (或暴击36)

8. 适配器模式(Adapter) ⭐⭐⭐⭐
// 适配不同的输入系统
public interface IInputSystem {
    Vector2 GetMovement();
    bool GetJumpButton();
    bool GetAttackButton();
}

// 旧的输入系统
public class OldInputSystem {
    public float GetHorizontal() => Input.GetAxis("Horizontal");
    public float GetVertical() => Input.GetAxis("Vertical");
    public bool GetSpace() => Input.GetKeyDown(KeyCode.Space);
    public bool GetMouse0() => Input.GetMouseButtonDown(0);
}

// 适配器
public class InputAdapter : IInputSystem {
    private OldInputSystem oldInput = new OldInputSystem();
    
    public Vector2 GetMovement() {
        return new Vector2(oldInput.GetHorizontal(), oldInput.GetVertical());
    }
    
    public bool GetJumpButton() => oldInput.GetSpace();
    public bool GetAttackButton() => oldInput.GetMouse0();
}

// 新的输入系统(Unity Input System)
using UnityEngine.InputSystem;

public class NewInputAdapter : IInputSystem {
    private PlayerInput playerInput;
    
    public NewInputAdapter() {
        playerInput = new PlayerInput();
        playerInput.Enable();
    }
    
    public Vector2 GetMovement() {
        return playerInput.Player.Move.ReadValue<Vector2>();
    }
    
    public bool GetJumpButton() {
        return playerInput.Player.Jump.triggered;
    }
    
    public bool GetAttackButton() {
        return playerInput.Player.Attack.triggered;
    }
}

// 使用(统一接口)
public class PlayerController : MonoBehaviour {
    private IInputSystem input;
    
    void Start() {
        // 可以轻松切换输入系统
        #if USE_NEW_INPUT
        input = new NewInputAdapter();
        #else
        input = new InputAdapter();
        #endif
    }
    
    void Update() {
        Vector2 movement = input.GetMovement();
        if (input.GetJumpButton()) {
            Jump();
        }
    }
    
    void Jump() { }
}

9. 外观模式(Facade) ⭐⭐⭐⭐⭐
// 简化复杂子系统
public class AudioFacade : MonoBehaviour {
    private AudioSource bgmSource;
    private AudioSource sfxSource;
    private Dictionary<string, AudioClip> audioClips;
    
    // 简化的接口
    public void PlayBGM(string bgmName, bool loop = true) {
        AudioClip clip = GetClip(bgmName);
        bgmSource.clip = clip;
        bgmSource.loop = loop;
        bgmSource.Play();
    }
    
    public void PlaySFX(string sfxName, float volume = 1f) {
        AudioClip clip = GetClip(sfxName);
        sfxSource.PlayOneShot(clip, volume);
    }
    
    public void StopBGM(float fadeTime = 1f) {
        StartCoroutine(FadeOut(bgmSource, fadeTime));
    }
    
    public void SetBGMVolume(float volume) {
        bgmSource.volume = volume;
    }
    
    public void SetSFXVolume(float volume) {
        sfxSource.volume = volume;
    }
    
    // 隐藏复杂实现
    private AudioClip GetClip(string name) {
        if (!audioClips.ContainsKey(name)) {
            audioClips[name] = Resources.Load<AudioClip>($"Audio/{name}");
        }
        return audioClips[name];
    }
    
    private IEnumerator FadeOut(AudioSource source, float time) {
        float startVolume = source.volume;
        while (source.volume > 0) {
            source.volume -= startVolume * Time.deltaTime / time;
            yield return null;
        }
        source.Stop();
        source.volume = startVolume;
    }
}

// 使用(简单调用)
AudioFacade.Instance.PlayBGM("battle_theme");
AudioFacade.Instance.PlaySFX("explosion", 0.8f);

🎭 行为型模式(Behavioral Patterns)

10. 观察者模式(Observer) ⭐⭐⭐⭐⭐
// Unity事件系统的基础
// A. C# Event实现
public class Player : MonoBehaviour {
    public delegate void HealthChangedHandler(int currentHealth, int maxHealth);
    public event HealthChangedHandler OnHealthChanged;
    
    public delegate void PlayerDiedHandler();
    public event PlayerDiedHandler OnPlayerDied;
    
    private int health = 100;
    private int maxHealth = 100;
    
    public void TakeDamage(int damage) {
        health -= damage;
        
        // 通知观察者
        OnHealthChanged?.Invoke(health, maxHealth);
        
        if (health <= 0) {
            OnPlayerDied?.Invoke();
        }
    }
}

// 观察者
public class HealthUI : MonoBehaviour {
    public Slider healthBar;
    public Player player;
    
    void Start() {
        // 订阅事件
        player.OnHealthChanged += UpdateHealthBar;
        player.OnPlayerDied += ShowDeathScreen;
    }
    
    void OnDestroy() {
        // 取消订阅(重要!)
        player.OnHealthChanged -= UpdateHealthBar;
        player.OnPlayerDied -= ShowDeathScreen;
    }
    
    void UpdateHealthBar(int current, int max) {
        healthBar.value = (float)current / max;
    }
    
    void ShowDeathScreen() {
        Debug.Log("显示死亡界面");
    }
}

// B. UnityEvent实现
using UnityEngine.Events;

[System.Serializable]
public class HealthEvent : UnityEvent<int, int> { }

public class ModernPlayer : MonoBehaviour {
    public HealthEvent onHealthChanged;
    public UnityEvent onPlayerDied;
    
    private int health = 100;
    
    public void TakeDamage(int damage) {
        health -= damage;
        onHealthChanged?.Invoke(health, 100);
        
        if (health <= 0) {
            onPlayerDied?.Invoke();
        }
    }
}

11. 命令模式(Command) ⭐⭐⭐⭐⭐
// 将操作封装成对象,支持撤销/重做
public interface ICommand {
    void Execute();
    void Undo();
}

// 移动命令
public class MoveCommand : ICommand {
    private Transform target;
    private Vector3 displacement;
    private Vector3 previousPosition;
    
    public MoveCommand(Transform target, Vector3 displacement) {
        this.target = target;
        this.displacement = displacement;
    }
    
    public void Execute() {
        previousPosition = target.position;
        target.position += displacement;
    }
    
    public void Undo() {
        target.position = previousPosition;
    }
}

// 旋转命令
public class RotateCommand : ICommand {
    private Transform target;
    private Vector3 rotation;
    private Quaternion previousRotation;
    
    public RotateCommand(Transform target, Vector3 rotation) {
        this.target = target;
        this.rotation = rotation;
    }
    
    public void Execute() {
        previousRotation = target.rotation;
        target.Rotate(rotation);
    }
    
    public void Undo() {
        target.rotation = previousRotation;
    }
}

// 改变颜色命令
public class ChangeColorCommand : ICommand {
    private Renderer renderer;
    private Color newColor;
    private Color previousColor;
    
    public ChangeColorCommand(Renderer renderer, Color color) {
        this.renderer = renderer;
        this.newColor = color;
    }
    
    public void Execute() {
        previousColor = renderer.material.color;
        renderer.material.color = newColor;
    }
    
    public void Undo() {
        renderer.material.color = previousColor;
    }
}

// 命令管理器(支持撤销/重做)
public class CommandManager : MonoBehaviour {
    private Stack<ICommand> commandHistory = new Stack<ICommand>();
    private Stack<ICommand> redoStack = new Stack<ICommand>();
    
    public void ExecuteCommand(ICommand command) {
        command.Execute();
        commandHistory.Push(command);
        redoStack.Clear();  // 执行新命令清空重做栈
    }
    
    public void Undo() {
        if (commandHistory.Count > 0) {
            ICommand command = commandHistory.Pop();
            command.Undo();
            redoStack.Push(command);
        }
    }
    
    public void Redo() {
        if (redoStack.Count > 0) {
            ICommand command = redoStack.Pop();
            command.Execute();
            commandHistory.Push(command);
        }
    }
    
    public void ClearHistory() {
        commandHistory.Clear();
        redoStack.Clear();
    }
}

// 使用示例
public class LevelEditor : MonoBehaviour {
    public Transform selectedObject;
    private CommandManager commandManager;
    
    void Start() {
        commandManager = GetComponent<CommandManager>();
    }
    
    void Update() {
        // 移动
        if (Input.GetKeyDown(KeyCode.W)) {
            commandManager.ExecuteCommand(
                new MoveCommand(selectedObject, Vector3.forward)
            );
        }
        
        // 撤销
        if (Input.GetKeyDown(KeyCode.Z) && Input.GetKey(KeyCode.LeftControl)) {
            commandManager.Undo();
        }
        
        // 重做
        if (Input.GetKeyDown(KeyCode.Y) && Input.GetKey(KeyCode.LeftControl)) {
            commandManager.Redo();
        }
    }
}

// 宏命令(组合多个命令)
public class MacroCommand : ICommand {
    private List<ICommand> commands = new List<ICommand>();
    
    public void AddCommand(ICommand command) {
        commands.Add(command);
    }
    
    public void Execute() {
        foreach (var command in commands) {
            command.Execute();
        }
    }
    
    public void Undo() {
        // 反向撤销
        for (int i = commands.Count - 1; i >= 0; i--) {
            commands[i].Undo();
        }
    }
}

// 使用宏命令
MacroCommand createCharacter = new MacroCommand();
createCharacter.AddCommand(new MoveCommand(character, spawnPoint));
createCharacter.AddCommand(new ChangeColorCommand(characterRenderer, Color.red));
createCharacter.AddCommand(new RotateCommand(character, new Vector3(0, 180, 0)));

commandManager.ExecuteCommand(createCharacter);  // 一次执行所有命令

应用场景:

  • 关卡编辑器(撤销/重做)
  • 回合制游戏(记录操作)
  • 输入缓冲(格斗游戏)
  • 录制回放系统

12. 状态模式(State) ⭐⭐⭐⭐⭐
// 将对象的状态封装成独立的类
public interface IState {
    void Enter();
    void Update();
    void FixedUpdate();
    void Exit();
}

// 状态机
public class StateMachine {
    private IState currentState;
    
    public void ChangeState(IState newState) {
        currentState?.Exit();
        currentState = newState;
        currentState?.Enter();
    }
    
    public void Update() {
        currentState?.Update();
    }
    
    public void FixedUpdate() {
        currentState?.FixedUpdate();
    }
}

// 具体状态:空闲
public class IdleState : IState {
    private PlayerController player;
    
    public IdleState(PlayerController player) {
        this.player = player;
    }
    
    public void Enter() {
        Debug.Log("进入Idle状态");
        player.Animator.Play("Idle");
    }
    
    public void Update() {
        // 状态转换逻辑
        if (Input.GetAxis("Horizontal") != 0 || Input.GetAxis("Vertical") != 0) {
            player.StateMachine.ChangeState(new RunState(player));
        }
        
        if (Input.GetKeyDown(KeyCode.Space)) {
            player.StateMachine.ChangeState(new JumpState(player));
        }
        
        if (Input.GetMouseButtonDown(0)) {
            player.StateMachine.ChangeState(new AttackState(player));
        }
    }
    
    public void FixedUpdate() { }
    
    public void Exit() {
        Debug.Log("离开Idle状态");
    }
}

// 具体状态:跑步
public class RunState : IState {
    private PlayerController player;
    private float moveSpeed = 5f;
    
    public RunState(PlayerController player) {
        this.player = player;
    }
    
    public void Enter() {
        Debug.Log("进入Run状态");
        player.Animator.Play("Run");
    }
    
    public void Update() {
        if (Input.GetAxis("Horizontal") == 0 && Input.GetAxis("Vertical") == 0) {
            player.StateMachine.ChangeState(new IdleState(player));
        }
        
        if (Input.GetKeyDown(KeyCode.Space)) {
            player.StateMachine.ChangeState(new JumpState(player));
        }
    }
    
    public void FixedUpdate() {
        // 移动逻辑
        float horizontal = Input.GetAxis("Horizontal");
        float vertical = Input.GetAxis("Vertical");
        Vector3 direction = new Vector3(horizontal, 0, vertical).normalized;
        
        player.Rigidbody.MovePosition(
            player.transform.position + direction * moveSpeed * Time.fixedDeltaTime
        );
    }
    
    public void Exit() { }
}

// 具体状态:跳跃
public class JumpState : IState {
    private PlayerController player;
    private float jumpForce = 5f;
    
    public JumpState(PlayerController player) {
        this.player = player;
    }
    
    public void Enter() {
        Debug.Log("进入Jump状态");
        player.Animator.Play("Jump");
        player.Rigidbody.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
    }
    
    public void Update() {
        // 检测落地
        if (player.IsGrounded()) {
            player.StateMachine.ChangeState(new IdleState(player));
        }
    }
    
    public void FixedUpdate() { }
    
    public void Exit() { }
}

// 具体状态:攻击
public class AttackState : IState {
    private PlayerController player;
    private float attackDuration = 0.5f;
    private float elapsedTime;
    
    public AttackState(PlayerController player) {
        this.player = player;
    }
    
    public void Enter() {
        Debug.Log("进入Attack状态");
        player.Animator.Play("Attack");
        elapsedTime = 0;
        
        // 攻击判定
        Collider[] hitColliders = Physics.OverlapSphere(
            player.transform.position + player.transform.forward,
            1f
        );
        
        foreach (var col in hitColliders) {
            if (col.CompareTag("Enemy")) {
                col.GetComponent<Enemy>()?.TakeDamage(10);
            }
        }
    }
    
    public void Update() {
        elapsedTime += Time.deltaTime;
        
        // 攻击动画结束
        if (elapsedTime >= attackDuration) {
            player.StateMachine.ChangeState(new IdleState(player));
        }
    }
    
    public void FixedUpdate() { }
    
    public void Exit() { }
}

// 玩家控制器
public class PlayerController : MonoBehaviour {
    public StateMachine StateMachine { get; private set; }
    public Animator Animator { get; private set; }
    public Rigidbody Rigidbody { get; private set; }
    
    void Awake() {
        StateMachine = new StateMachine();
        Animator = GetComponent<Animator>();
        Rigidbody = GetComponent<Rigidbody>();
    }
    
    void Start() {
        // 初始状态
        StateMachine.ChangeState(new IdleState(this));
    }
    
    void Update() {
        StateMachine.Update();
    }
    
    void FixedUpdate() {
        StateMachine.FixedUpdate();
    }
    
    public bool IsGrounded() {
        return Physics.Raycast(transform.position, Vector3.down, 1.1f);
    }
}

// 敌人AI状态机
public class EnemyAI : MonoBehaviour {
    public enum State { Idle, Patrol, Chase, Attack }
    
    private State currentState;
    private Transform player;
    private float detectionRange = 10f;
    private float attackRange = 2f;
    
    void Update() {
        switch (currentState) {
            case State.Idle:
                IdleUpdate();
                break;
            case State.Patrol:
                PatrolUpdate();
                break;
            case State.Chase:
                ChaseUpdate();
                break;
            case State.Attack:
                AttackUpdate();
                break;
        }
    }
    
    void IdleUpdate() {
        if (PlayerInRange(detectionRange)) {
            ChangeState(State.Chase);
        }
    }
    
    void PatrolUpdate() {
        // 巡逻逻辑
        if (PlayerInRange(detectionRange)) {
            ChangeState(State.Chase);
        }
    }
    
    void ChaseUpdate() {
        if (PlayerInRange(attackRange)) {
            ChangeState(State.Attack);
        } else if (!PlayerInRange(detectionRange)) {
            ChangeState(State.Patrol);
        } else {
            // 追逐玩家
            Vector3 direction = (player.position - transform.position).normalized;
            transform.position += direction * 3f * Time.deltaTime;
        }
    }
    
    void AttackUpdate() {
        if (!PlayerInRange(attackRange)) {
            ChangeState(State.Chase);
        } else {
            // 攻击逻辑
        }
    }
    
    void ChangeState(State newState) {
        currentState = newState;
        Debug.Log($"Enemy state changed to: {newState}");
    }
    
    bool PlayerInRange(float range) {
        return Vector3.Distance(transform.position, player.position) < range;
    }
}

应用场景:

  • 角色控制器(Idle/Run/Jump/Attack)
  • AI状态机
  • UI状态管理
  • 游戏流程(Menu/Playing/Paused/GameOver)

13. 策略模式(Strategy) ⭐⭐⭐⭐⭐
// 封装算法,使其可以互换
public interface IAttackStrategy {
    void Attack(Enemy enemy);
}

// 具体策略:近战攻击
public class MeleeAttackStrategy : IAttackStrategy {
    public void Attack(Enemy enemy) {
        Debug.Log("近战攻击");
        
        Collider[] hits = Physics.OverlapSphere(enemy.transform.position, 2f);
        foreach (var hit in hits) {
            if (hit.CompareTag("Enemy")) {
                hit.GetComponent<Enemy>()?.TakeDamage(10);
            }
        }
    }
}

// 具体策略:远程攻击
public class RangedAttackStrategy : IAttackStrategy {
    private GameObject bulletPrefab;
    
    public RangedAttackStrategy(GameObject bulletPrefab) {
        this.bulletPrefab = bulletPrefab;
    }
    
    public void Attack(Enemy enemy) {
        Debug.Log("远程攻击");
        
        GameObject bullet = Object.Instantiate(bulletPrefab);
        bullet.transform.position = enemy.transform.position;
        
        Vector3 direction = (enemy.transform.forward).normalized;
        bullet.GetComponent<Rigidbody>().velocity = direction * 10f;
    }
}

// 具体策略:魔法攻击
public class MagicAttackStrategy : IAttackStrategy {
    private ParticleSystem magicEffect;
    
    public MagicAttackStrategy(ParticleSystem effect) {
        this.magicEffect = effect;
    }
    
    public void Attack(Enemy enemy) {
        Debug.Log("魔法攻击");
        
        ParticleSystem effect = Object.Instantiate(magicEffect);
        effect.transform.position = enemy.transform.position;
        effect.Play();
        
        // AOE伤害
        Collider[] hits = Physics.OverlapSphere(enemy.transform.position, 5f);
        foreach (var hit in hits) {
            if (hit.CompareTag("Enemy")) {
                hit.GetComponent<Enemy>()?.TakeDamage(15);
            }
        }
    }
}

// 使用策略的类
public class Weapon : MonoBehaviour {
    private IAttackStrategy attackStrategy;
    
    public void SetAttackStrategy(IAttackStrategy strategy) {
        attackStrategy = strategy;
    }
    
    public void Attack() {
        attackStrategy?.Attack(GetComponent<Enemy>());
    }
}

// 使用
public class Player : MonoBehaviour {
    private Weapon weapon;
    
    void Start() {
        weapon = GetComponent<Weapon>();
        
        // 初始策略:近战
        weapon.SetAttackStrategy(new MeleeAttackStrategy());
    }
    
    void Update() {
        if (Input.GetKeyDown(KeyCode.Alpha1)) {
            // 切换到近战
            weapon.SetAttackStrategy(new MeleeAttackStrategy());
        }
        else if (Input.GetKeyDown(KeyCode.Alpha2)) {
            // 切换到远程
            weapon.SetAttackStrategy(new RangedAttackStrategy(bulletPrefab));
        }
        else if (Input.GetKeyDown(KeyCode.Alpha3)) {
            // 切换到魔法
            weapon.SetAttackStrategy(new MagicAttackStrategy(magicEffectPrefab));
        }
        
        if (Input.GetKeyDown(KeyCode.Space)) {
            weapon.Attack();
        }
    }
    
    public GameObject bulletPrefab;
    public ParticleSystem magicEffectPrefab;
}

// 寻路策略
public interface IPathfindingStrategy {
    List<Vector3> FindPath(Vector3 start, Vector3 end);
}

public class AStarStrategy : IPathfindingStrategy {
    public List<Vector3> FindPath(Vector3 start, Vector3 end) {
        Debug.Log("使用A*寻路");
        // A*算法实现
        return new List<Vector3>();
    }
}

public class DijkstraStrategy : IPathfindingStrategy {
    public List<Vector3> FindPath(Vector3 start, Vector3 end) {
        Debug.Log("使用Dijkstra寻路");
        // Dijkstra算法实现
        return new List<Vector3>();
    }
}

public class NavMeshStrategy : IPathfindingStrategy {
    public List<Vector3> FindPath(Vector3 start, Vector3 end) {
        Debug.Log("使用NavMesh寻路");
        // Unity NavMesh
        return new List<Vector3>();
    }
}

// AI根据地形选择寻路策略
public class AIController : MonoBehaviour {
    private IPathfindingStrategy pathfinding;
    
    void Start() {
        // 根据场景选择策略
        if (IsIndoorScene()) {
            pathfinding = new NavMeshStrategy();
        } else if (IsLargeOpenWorld()) {
            pathfinding = new AStarStrategy();
        } else {
            pathfinding = new DijkstraStrategy();
        }
    }
    
    void MoveTo(Vector3 target) {
        List<Vector3> path = pathfinding.FindPath(transform.position, target);
        // 沿路径移动
    }
    
    bool IsIndoorScene() { return true; }
    bool IsLargeOpenWorld() { return false; }
}

应用场景:

  • 不同的攻击方式
  • 不同的寻路算法
  • 不同的排序算法
  • 不同的存档格式

14. 模板方法模式(Template Method) ⭐⭐⭐⭐
// 定义算法骨架,子类实现具体步骤
public abstract class GameLevel {
    // 模板方法(定义流程)
    public void PlayLevel() {
        LoadAssets();
        InitializeLevel();
        SpawnPlayer();
        SpawnEnemies();
        StartGameLoop();
        
        // 可选步骤
        if (HasBoss()) {
            SpawnBoss();
        }
        
        CleanUp();
    }
    
    // 抽象方法(子类必须实现)
    protected abstract void LoadAssets();
    protected abstract void InitializeLevel();
    protected abstract void SpawnEnemies();
    
    // 钩子方法(子类可选实现)
    protected virtual bool HasBoss() => false;
    protected virtual void SpawnBoss() { }
    
    // 具体方法(共用实现)
    protected void SpawnPlayer() {
        Debug.Log("生成玩家");
    }
    
    protected void StartGameLoop() {
        Debug.Log("开始游戏循环");
    }
    
    protected void CleanUp() {
        Debug.Log("清理资源");
    }
}

// 具体实现:森林关卡
public class ForestLevel : GameLevel {
    protected override void LoadAssets() {
        Debug.Log("加载森林资源");
    }
    
    protected override void InitializeLevel() {
        Debug.Log("初始化森林地形");
    }
    
    protected override void SpawnEnemies() {
        Debug.Log("生成森林怪物:哥布林、树人");
    }
}

// 具体实现:地下城关卡
public class DungeonLevel : GameLevel {
    protected override void LoadAssets() {
        Debug.Log("加载地下城资源");
    }
    
    protected override void InitializeLevel() {
        Debug.Log("初始化地下城");
    }
    
    protected override void SpawnEnemies() {
        Debug.Log("生成地下城怪物:骷髅、恶魔");
    }
    
    protected override bool HasBoss() => true;
    
    protected override void SpawnBoss() {
        Debug.Log("生成Boss:恶魔领主");
    }
}

// 使用
public class GameManager : MonoBehaviour {
    void StartLevel(int levelIndex) {
        GameLevel level;
        
        switch (levelIndex) {
            case 1:
                level = new ForestLevel();
                break;
            case 2:
                level = new DungeonLevel();
                break;
            default:
                return;
        }
        
        level.PlayLevel();
    }
}

// UI动画模板
public abstract class UIAnimation {
    public void PlayAnimation() {
        Prepare();
        AnimateIn();
        Hold();
        AnimateOut();
        Complete();
    }
    
    protected virtual void Prepare() {
        Debug.Log("准备动画");
    }
    
    protected abstract void AnimateIn();
    protected abstract void AnimateOut();
    
    protected virtual void Hold() {
        // 默认停留1秒
        System.Threading.Thread.Sleep(1000);
    }
    
    protected virtual void Complete() {
        Debug.Log("动画完成");
    }
}

public class FadeAnimation : UIAnimation {
    private CanvasGroup canvasGroup;
    
    public FadeAnimation(CanvasGroup cg) {
        canvasGroup = cg;
    }
    
    protected override void AnimateIn() {
        Debug.Log("淡入");
        canvasGroup.alpha = 0;
        // DOTween.To(() => canvasGroup.alpha, x => canvasGroup.alpha = x, 1, 0.5f);
    }
    
    protected override void AnimateOut() {
        Debug.Log("淡出");
        // DOTween.To(() => canvasGroup.alpha, x => canvasGroup.alpha = x, 0, 0.5f);
    }
}

public class ScaleAnimation : UIAnimation {
    private Transform target;
    
    public ScaleAnimation(Transform t) {
        target = t;
    }
    
    protected override void AnimateIn() {
        Debug.Log("缩放进入");
        target.localScale = Vector3.zero;
        // DOTween.To(() => target.localScale, x => target.localScale = x, Vector3.one, 0.5f);
    }
    
    protected override void AnimateOut() {
        Debug.Log("缩放退出");
        // DOTween.To(() => target.localScale, x => target.localScale = x, Vector3.zero, 0.5f);
    }
}

15. 责任链模式(Chain of Responsibility) ⭐⭐⭐⭐
// 请求沿着处理者链传递
public abstract class DamageHandler {
    protected DamageHandler nextHandler;
    
    public void SetNext(DamageHandler handler) {
        nextHandler = handler;
    }
    
    public abstract int HandleDamage(int damage, DamageType type);
}

public enum DamageType {
    Physical,
    Magic,
    Fire,
    Ice,
    Poison
}

// 护甲处理器
public class ArmorHandler : DamageHandler {
    private int armorValue = 10;
    
    public override int HandleDamage(int damage, DamageType type) {
        if (type == DamageType.Physical) {
            damage = Mathf.Max(0, damage - armorValue);
            Debug.Log($"护甲减免,剩余伤害: {damage}");
        }
        
        return nextHandler != null ? nextHandler.HandleDamage(damage, type) : damage;
    }
}

// 魔抗处理器
public class MagicResistHandler : DamageHandler {
    private float resistPercent = 0.3f;
    
    public override int HandleDamage(int damage, DamageType type) {
        if (type == DamageType.Magic) {
            damage = Mathf.RoundToInt(damage * (1 - resistPercent));
            Debug.Log($"魔抗减免,剩余伤害: {damage}");
        }
        
        return nextHandler != null ? nextHandler.HandleDamage(damage, type) : damage;
    }
}

// 护盾处理器
public class ShieldHandler : DamageHandler {
    private int shieldValue = 50;
    
    public override int HandleDamage(int damage, DamageType type) {
        if (shieldValue > 0) {
            int absorbed = Mathf.Min(damage, shieldValue);
            shieldValue -= absorbed;
            damage -= absorbed;
            Debug.Log($"护盾吸收{absorbed}伤害,剩余伤害: {damage}");
        }
        
        return nextHandler != null ? nextHandler.HandleDamage(damage, type) : damage;
    }
}

// Buff处理器
public class BuffHandler : DamageHandler {
    private bool hasImmunity = false;
    private float damageReduction = 0.2f;
    
    public override int HandleDamage(int damage, DamageType type) {
        if (hasImmunity) {
            Debug.Log("免疫伤害");
            return 0;
        }
        
        damage = Mathf.RoundToInt(damage * (1 - damageReduction));
        Debug.Log($"Buff减免,剩余伤害: {damage}");
        
        return nextHandler != null ? nextHandler.HandleDamage(damage, type) : damage;
    }
}

// 使用责任链
public class Character : MonoBehaviour {
    private DamageHandler damageChain;
    private int health = 100;
    
    void Start() {
        // 构建责任链
        damageChain = new ShieldHandler();
        var armorHandler = new ArmorHandler();
        var magicResistHandler = new MagicResistHandler();
        var buffHandler = new BuffHandler();
        
        damageChain.SetNext(armorHandler);
        armorHandler.SetNext(magicResistHandler);
        magicResistHandler.SetNext(buffHandler);
    }
    
    public void TakeDamage(int damage, DamageType type) {
        // 伤害经过责任链处理
        int finalDamage = damageChain.HandleDamage(damage, type);
        
        health -= finalDamage;
        Debug.Log($"最终受到{finalDamage}伤害,剩余血量: {health}");
    }
}

// 使用
character.TakeDamage(100, DamageType.Physical);
// 输出:
// 护盾吸收50伤害,剩余伤害: 50
// 护甲减免,剩余伤害: 40
// Buff减免,剩余伤害: 32
// 最终受到32伤害,剩余血量: 68

// 输入处理链
public abstract class InputHandler {
    protected InputHandler nextHandler;
    
    public void SetNext(InputHandler handler) {
        nextHandler = handler;
    }
    
    public abstract bool Handle(KeyCode key);
}

public class UIInputHandler : InputHandler {
    public override bool Handle(KeyCode key) {
        if (key == KeyCode.Escape) {
            Debug.Log("UI处理:打开菜单");
            return true;  // 处理完毕,不传递
        }
        
        return nextHandler != null && nextHandler.Handle(key);
    }
}

public class PlayerInputHandler : InputHandler {
    public override bool Handle(KeyCode key) {
        if (key == KeyCode.Space) {
            Debug.Log("玩家处理:跳跃");
            return true;
        }
        
        return nextHandler != null && nextHandler.Handle(key);
    }
}

public class CheatInputHandler : InputHandler {
    public override bool Handle(KeyCode key) {
        if (key == KeyCode.F1) {
            Debug.Log("作弊处理:无敌模式");
            return true;
        }
        
        return nextHandler != null && nextHandler.Handle(key);
    }
}

16. 访问者模式(Visitor) ⭐⭐⭐
// 在不修改类结构的情况下添加新操作
public interface IVisitor {
    void Visit(Player player);
    void Visit(Enemy enemy);
    void Visit(NPC npc);
}

public interface IVisitable {
    void Accept(IVisitor visitor);
}

// 具体访问者:治疗访问者
public class HealVisitor : IVisitor {
    private int healAmount = 20;
    
    public void Visit(Player player) {
        player.Health += healAmount;
        Debug.Log($"玩家恢复{healAmount}生命值");
    }
    
    public void Visit(Enemy enemy) {
        // 敌人不受治疗影响
        Debug.Log("敌人不能被治疗");
    }
    
    public void Visit(NPC npc) {
        npc.Health += healAmount;
        Debug.Log($"NPC恢复{healAmount}生命值");
    }
}

// 具体访问者:伤害访问者
public class DamageVisitor : IVisitor {
    private int damageAmount = 50;
    
    public void Visit(Player player) {
        player.Health -= damageAmount;
        Debug.Log($"玩家受到{damageAmount}伤害");
    }
    
    public void Visit(Enemy enemy) {
        enemy.Health -= damageAmount * 2;  // 敌人受到双倍伤害
        Debug.Log($"敌人受到{damageAmount * 2}伤害");
    }
    
    public void Visit(NPC npc) {
        npc.Health -= damageAmount / 2;  // NPC只受到一半伤害
        Debug.Log($"NPC受到{damageAmount / 2}伤害");
    }
}

// 具体访问者:属性显示访问者
public class InfoVisitor : IVisitor {
    public void Visit(Player player) {
        Debug.Log($"玩家信息 - 生命:{player.Health}, 等级:{player.Level}");
    }
    
    public void Visit(Enemy enemy) {
        Debug.Log($"敌人信息 - 生命:{enemy.Health}, 类型:{enemy.EnemyType}");
    }
    
    public void Visit(NPC npc) {
        Debug.Log($"NPC信息 - 生命:{npc.Health}, 名字:{npc.Name}");
    }
}

// 可访问的对象
public class Player : MonoBehaviour, IVisitable {
    public int Health = 100;
    public int Level = 1;
    
    public void Accept(IVisitor visitor) {
        visitor.Visit(this);
    }
}

public class Enemy : MonoBehaviour, IVisitable {
    public int Health = 50;
    public string EnemyType = "Goblin";
    
    public void Accept(IVisitor visitor) {
        visitor.Visit(this);
    }
}

public class NPC : MonoBehaviour, IVisitable {
    public int Health = 80;
    public string Name = "村民";
    
    public void Accept(IVisitor visitor) {
        visitor.Visit(this);
    }
}

// 使用示例
public class GameController : MonoBehaviour {
    void Start() {
        List<IVisitable> entities = new List<IVisitable> {
            new Player(),
            new Enemy(),
            new NPC()
        };
        
        // 治疗所有单位
        IVisitor healVisitor = new HealVisitor();
        foreach (var entity in entities) {
            entity.Accept(healVisitor);
        }
        
        // 对所有单位造成伤害
        IVisitor damageVisitor = new DamageVisitor();
        foreach (var entity in entities) {
            entity.Accept(damageVisitor);
        }
        
        // 显示所有单位信息
        IVisitor infoVisitor = new InfoVisitor();
        foreach (var entity in entities) {
            entity.Accept(infoVisitor);
        }
    }
}

// Buff系统使用访问者
public class BuffVisitor : IVisitor {
    public enum BuffType { Speed, Damage, Defense }
    private BuffType buffType;
    private float buffValue;
    
    public BuffVisitor(BuffType type, float value) {
        buffType = type;
        buffValue = value;
    }
    
    public void Visit(Player player) {
        switch (buffType) {
            case BuffType.Speed:
                player.MoveSpeed *= buffValue;
                break;
            case BuffType.Damage:
                player.AttackDamage += (int)buffValue;
                break;
            case BuffType.Defense:
                player.Defense += (int)buffValue;
                break;
        }
    }
    
    public void Visit(Enemy enemy) {
        // 敌人不受Buff影响
    }
    
    public void Visit(NPC npc) {
        // NPC不受Buff影响
    }
}

应用场景:

  • Buff/Debuff系统
  • AOE技能效果
  • 场景对象批量操作
  • 数据统计/序列化

17. 中介者模式(Mediator) ⭐⭐⭐⭐
// 用中介者对象封装对象间的交互
public interface IMediator {
    void Notify(Component sender, string eventName);
}

// 战斗系统中介者
public class BattleMediator : IMediator {
    private Player player;
    private List<Enemy> enemies = new List<Enemy>();
    private BattleUI ui;
    private ScoreSystem scoreSystem;
    
    public void RegisterPlayer(Player p) {
        player = p;
        player.SetMediator(this);
    }
    
    public void RegisterEnemy(Enemy e) {
        enemies.Add(e);
        e.SetMediator(this);
    }
    
    public void RegisterUI(BattleUI battleUI) {
        ui = battleUI;
    }
    
    public void RegisterScoreSystem(ScoreSystem score) {
        scoreSystem = score;
    }
    
    public void Notify(Component sender, string eventName) {
        switch (eventName) {
            case "PlayerAttack":
                OnPlayerAttack();
                break;
                
            case "EnemyDead":
                OnEnemyDead(sender as Enemy);
                break;
                
            case "PlayerTakeDamage":
                OnPlayerTakeDamage();
                break;
                
            case "PlayerDead":
                OnPlayerDead();
                break;
        }
    }
    
    void OnPlayerAttack() {
        // 找最近的敌人
        Enemy nearestEnemy = FindNearestEnemy();
        if (nearestEnemy != null) {
            nearestEnemy.TakeDamage(player.AttackDamage);
        }
    }
    
    void OnEnemyDead(Enemy enemy) {
        enemies.Remove(enemy);
        scoreSystem.AddScore(100);
        ui.UpdateEnemyCount(enemies.Count);
        
        // 检查胜利条件
        if (enemies.Count == 0) {
            ui.ShowVictory();
        }
    }
    
    void OnPlayerTakeDamage() {
        ui.UpdateHealthBar(player.Health, player.MaxHealth);
        
        // 屏幕震动
        Camera.main.GetComponent<CameraShake>()?.Shake();
    }
    
    void OnPlayerDead() {
        // 停止所有敌人AI
        foreach (var enemy in enemies) {
            enemy.Stop();
        }
        
        ui.ShowGameOver();
        scoreSystem.SaveHighScore();
    }
    
    Enemy FindNearestEnemy() {
        Enemy nearest = null;
        float minDistance = float.MaxValue;
        
        foreach (var enemy in enemies) {
            float distance = Vector3.Distance(player.transform.position, enemy.transform.position);
            if (distance < minDistance) {
                minDistance = distance;
                nearest = enemy;
            }
        }
        
        return nearest;
    }
}

// 组件基类
public abstract class Component : MonoBehaviour {
    protected IMediator mediator;
    
    public void SetMediator(IMediator m) {
        mediator = m;
    }
}

// 玩家
public class Player : Component {
    public int Health = 100;
    public int MaxHealth = 100;
    public int AttackDamage = 10;
    
    public void Attack() {
        mediator?.Notify(this, "PlayerAttack");
    }
    
    public void TakeDamage(int damage) {
        Health -= damage;
        mediator?.Notify(this, "PlayerTakeDamage");
        
        if (Health <= 0) {
            mediator?.Notify(this, "PlayerDead");
        }
    }
}

// 敌人
public class Enemy : Component {
    public int Health = 50;
    
    public void TakeDamage(int damage) {
        Health -= damage;
        
        if (Health <= 0) {
            mediator?.Notify(this, "EnemyDead");
            Destroy(gameObject);
        }
    }
    
    public void Stop() {
        // 停止AI
        GetComponent<EnemyAI>().enabled = false;
    }
}

// UI管理器中介者
public class UIMediator : MonoBehaviour {
    private Dictionary<string, UIPanel> panels = new Dictionary<string, UIPanel>();
    
    public void RegisterPanel(string name, UIPanel panel) {
        panels[name] = panel;
        panel.SetMediator(this);
    }
    
    public void ShowPanel(string name) {
        // 隐藏所有面板
        foreach (var panel in panels.Values) {
            panel.Hide();
        }
        
        // 显示指定面板
        if (panels.TryGetValue(name, out UIPanel targetPanel)) {
            targetPanel.Show();
        }
    }
    
    public void OnButtonClick(string buttonName) {
        switch (buttonName) {
            case "StartGame":
                ShowPanel("GamePanel");
                break;
            case "Settings":
                ShowPanel("SettingsPanel");
                break;
            case "Back":
                ShowPanel("MainMenu");
                break;
        }
    }
}

public class UIPanel : MonoBehaviour {
    protected UIMediator mediator;
    
    public void SetMediator(UIMediator m) {
        mediator = m;
    }
    
    public virtual void Show() {
        gameObject.SetActive(true);
    }
    
    public virtual void Hide() {
        gameObject.SetActive(false);
    }
}

应用场景:

  • 战斗系统协调
  • UI面板管理
  • 多人联机通信
  • 游戏流程控制

18. 备忘录模式(Memento) ⭐⭐⭐⭐
// 保存和恢复对象状态
// 存档系统
[System.Serializable]
public class GameMemento {
    public int playerLevel;
    public int playerHealth;
    public Vector3 playerPosition;
    public List<int> inventory;
    public Dictionary<string, bool> questStatus;
    public float playTime;
    public string saveTime;
    
    public GameMemento(GameState state) {
        playerLevel = state.Level;
        playerHealth = state.Health;
        playerPosition = state.Position;
        inventory = new List<int>(state.Inventory);
        questStatus = new Dictionary<string, bool>(state.QuestStatus);
        playTime = state.PlayTime;
        saveTime = System.DateTime.Now.ToString();
    }
}

// 游戏状态(原发器)
public class GameState {
    public int Level = 1;
    public int Health = 100;
    public Vector3 Position = Vector3.zero;
    public List<int> Inventory = new List<int>();
    public Dictionary<string, bool> QuestStatus = new Dictionary<string, bool>();
    public float PlayTime = 0;
    
    // 创建备忘录
    public GameMemento CreateMemento() {
        return new GameMemento(this);
    }
    
    // 从备忘录恢复
    public void RestoreMemento(GameMemento memento) {
        Level = memento.playerLevel;
        Health = memento.playerHealth;
        Position = memento.playerPosition;
        Inventory = new List<int>(memento.inventory);
        QuestStatus = new Dictionary<string, bool>(memento.questStatus);
        PlayTime = memento.playTime;
    }
}

// 存档管理器(守护者)
public class SaveManager : MonoBehaviour {
    private const string SAVE_KEY = "GameSave_";
    private Dictionary<int, GameMemento> saveSlots = new Dictionary<int, GameMemento>();
    
    public void Save(int slotIndex, GameState state) {
        GameMemento memento = state.CreateMemento();
        saveSlots[slotIndex] = memento;
        
        // 序列化保存
        string json = JsonUtility.ToJson(memento);
        PlayerPrefs.SetString(SAVE_KEY + slotIndex, json);
        PlayerPrefs.Save();
        
        Debug.Log($"游戏保存到插槽{slotIndex}");
    }
    
    public void Load(int slotIndex, GameState state) {
        string json = PlayerPrefs.GetString(SAVE_KEY + slotIndex, "");
        
        if (!string.IsNullOrEmpty(json)) {
            GameMemento memento = JsonUtility.FromJson<GameMemento>(json);
            state.RestoreMemento(memento);
            saveSlots[slotIndex] = memento;
            
            Debug.Log($"从插槽{slotIndex}加载游戏");
        } else {
            Debug.LogWarning($"插槽{slotIndex}没有存档");
        }
    }
    
    public bool HasSave(int slotIndex) {
        return PlayerPrefs.HasKey(SAVE_KEY + slotIndex);
    }
    
    public void DeleteSave(int slotIndex) {
        PlayerPrefs.DeleteKey(SAVE_KEY + slotIndex);
        saveSlots.Remove(slotIndex);
    }
    
    public GameMemento GetSaveInfo(int slotIndex) {
        if (saveSlots.TryGetValue(slotIndex, out GameMemento memento)) {
            return memento;
        }
        
        string json = PlayerPrefs.GetString(SAVE_KEY + slotIndex, "");
        if (!string.IsNullOrEmpty(json)) {
            return JsonUtility.FromJson<GameMemento>(json);
        }
        
        return null;
    }
}

// 使用示例
public class GameManager : MonoBehaviour {
    private GameState gameState;
    private SaveManager saveManager;
    
    void Start() {
        gameState = new GameState();
        saveManager = GetComponent<SaveManager>();
    }
    
    void Update() {
        // F5快速保存
        if (Input.GetKeyDown(KeyCode.F5)) {
            saveManager.Save(0, gameState);
        }
        
        // F9快速加载
        if (Input.GetKeyDown(KeyCode.F9)) {
            saveManager.Load(0, gameState);
        }
    }
}

// 撤销/重做系统(使用备忘录)
public class EditorHistory {
    private Stack<GameMemento> undoStack = new Stack<GameMemento>();
    private Stack<GameMemento> redoStack = new Stack<GameMemento>();
    private GameState currentState;
    
    public EditorHistory(GameState state) {
        currentState = state;
    }
    
    public void SaveState() {
        undoStack.Push(currentState.CreateMemento());
        redoStack.Clear();  // 新操作清空重做栈
    }
    
    public void Undo() {
        if (undoStack.Count > 0) {
            // 保存当前状态到重做栈
            redoStack.Push(currentState.CreateMemento());
            
            // 恢复上一个状态
            GameMemento memento = undoStack.Pop();
            currentState.RestoreMemento(memento);
            
            Debug.Log("撤销");
        }
    }
    
    public void Redo() {
        if (redoStack.Count > 0) {
            // 保存当前状态到撤销栈
            undoStack.Push(currentState.CreateMemento());
            
            // 恢复重做的状态
            GameMemento memento = redoStack.Pop();
            currentState.RestoreMemento(memento);
            
            Debug.Log("重做");
        }
    }
}

应用场景:

  • 存档系统
  • 关卡编辑器(撤销/重做)
  • 时间倒流机制
  • 回放系统

19. 迭代器模式(Iterator) ⭐⭐⭐
// C#天生支持迭代器(foreach、IEnumerable)
// 自定义迭代器:背包系统
public class Inventory : IEnumerable<Item> {
    private List<Item> items = new List<Item>();
    
    public void AddItem(Item item) {
        items.Add(item);
    }
    
    public void RemoveItem(Item item) {
        items.Remove(item);
    }
    
    // 普通迭代器
    public IEnumerator<Item> GetEnumerator() {
        return items.GetEnumerator();
    }
    
    IEnumerator IEnumerable.GetEnumerator() {
        return GetEnumerator();
    }
    
    // 自定义迭代器:只遍历武器
    public IEnumerable<Item> GetWeapons() {
        foreach (var item in items) {
            if (item.Type == ItemType.Weapon) {
                yield return item;
            }
        }
    }
    
    // 自定义迭代器:按稀有度排序
    public IEnumerable<Item> GetItemsByRarity() {
        return items.OrderByDescending(i => i.Rarity);
    }
    
    // 反向迭代器
    public IEnumerable<Item> GetItemsReverse() {
        for (int i = items.Count - 1; i >= 0; i--) {
            yield return items[i];
        }
    }
}

public class Item {
    public string Name;
    public ItemType Type;
    public int Rarity;
}

public enum ItemType {
    Weapon,
    Armor,
    Potion,
    Material
}

// 使用
public class PlayerInventory : MonoBehaviour {
    private Inventory inventory = new Inventory();
    
    void Start() {
        // 添加物品
        inventory.AddItem(new Item { Name = "剑", Type = ItemType.Weapon, Rarity = 3 });
        inventory.AddItem(new Item { Name = "盾", Type = ItemType.Armor, Rarity = 2 });
        
        // 遍历所有物品
        foreach (var item in inventory) {
            Debug.Log($"物品: {item.Name}");
        }
        
        // 只遍历武器
        foreach (var weapon in inventory.GetWeapons()) {
            Debug.Log($"武器: {weapon.Name}");
        }
        
        // 按稀有度遍历
        foreach (var item in inventory.GetItemsByRarity()) {
            Debug.Log($"稀有物品: {item.Name}, 稀有度: {item.Rarity}");
        }
    }
}

// 技能树迭代器
public class SkillTree {
    private Dictionary<int, SkillNode> nodes = new Dictionary<int, SkillNode>();
    
    public void AddNode(SkillNode node) {
        nodes[node.Id] = node;
    }
    
    // 广度优先遍历
    public IEnumerable<SkillNode> BreadthFirstTraversal(int startId) {
        Queue<int> queue = new Queue<int>();
        HashSet<int> visited = new HashSet<int>();
        
        queue.Enqueue(startId);
        visited.Add(startId);
        
        while (queue.Count > 0) {
            int currentId = queue.Dequeue();
            SkillNode node = nodes[currentId];
            
            yield return node;
            
            foreach (var childId in node.Children) {
                if (!visited.Contains(childId)) {
                    queue.Enqueue(childId);
                    visited.Add(childId);
                }
            }
        }
    }
    
    // 深度优先遍历
    public IEnumerable<SkillNode> DepthFirstTraversal(int startId) {
        HashSet<int> visited = new HashSet<int>();
        return DFSHelper(startId, visited);
    }
    
    private IEnumerable<SkillNode> DFSHelper(int nodeId, HashSet<int> visited) {
        if (visited.Contains(nodeId)) {
            yield break;
        }
        
        visited.Add(nodeId);
        SkillNode node = nodes[nodeId];
        
        yield return node;
        
        foreach (var childId in node.Children) {
            foreach (var child in DFSHelper(childId, visited)) {
                yield return child;
            }
        }
    }
}

public class SkillNode {
    public int Id;
    public string Name;
    public List<int> Children = new List<int>();
}

🎮 Unity特有的模式

20. 组件模式(Component Pattern) ⭐⭐⭐⭐⭐
// Unity的核心设计模式
// GameObject + Component 架构

// 功能组件化
public class Health : MonoBehaviour {
    public int maxHealth = 100;
    private int currentHealth;
    
    public event Action<int> OnHealthChanged;
    public event Action OnDeath;
    
    void Start() {
        currentHealth = maxHealth;
    }
    
    public void TakeDamage(int damage) {
        currentHealth -= damage;
        OnHealthChanged?.Invoke(currentHealth);
        
        if (currentHealth <= 0) {
            OnDeath?.Invoke();
        }
    }
    
    public void Heal(int amount) {
        currentHealth = Mathf.Min(currentHealth + amount, maxHealth);
        OnHealthChanged?.Invoke(currentHealth);
    }
}

public class Mover : MonoBehaviour {
    public float moveSpeed = 5f;
    
    public void Move(Vector3 direction) {
        transform.position += direction * moveSpeed * Time.deltaTime;
    }
}

public class Shooter : MonoBehaviour {
    public GameObject bulletPrefab;
    public Transform firePoint;
    public float fireRate = 0.5f;
    
    private float nextFireTime;
    
    public void Fire() {
        if (Time.time >= nextFireTime) {
            Instantiate(bulletPrefab, firePoint.position, firePoint.rotation);
            nextFireTime = Time.time + fireRate;
        }
    }
}

// 组合组件
public class Player : MonoBehaviour {
    private Health health;
    private Mover mover;
    private Shooter shooter;
    
    void Awake() {
        health = GetComponent<Health>();
        mover = GetComponent<Mover>();
        shooter = GetComponent<Shooter>();
    }
    
    void Update() {
        // 移动
        float horizontal = Input.GetAxis("Horizontal");
        float vertical = Input.GetAxis("Vertical");
        mover.Move(new Vector3(horizontal, 0, vertical));
        
        // 射击
        if (Input.GetButton("Fire1")) {
            shooter.Fire();
        }
    }
}

21. 更新方法模式(Update Method) ⭐⭐⭐⭐⭐
// Unity的Update就是这个模式
// 集中管理更新逻辑
public class UpdateManager : MonoSingleton<UpdateManager> {
    private List<IUpdatable> updatables = new List<IUpdatable>();
    
    public void Register(IUpdatable updatable) {
        if (!updatables.Contains(updatable)) {
            updatables.Add(updatable);
        }
    }
    
    public void Unregister(IUpdatable updatable) {
        updatables.Remove(updatable);
    }
    
    void Update() {
        // 统一调用所有注册对象的更新
        for (int i = updatables.Count - 1; i >= 0; i--) {
            updatables[i].OnUpdate(Time.deltaTime);
        }
    }
}

public interface IUpdatable {
    void OnUpdate(float deltaTime);
}

// 不继承MonoBehaviour的类也能使用Update
public class CustomLogic : IUpdatable {
    public void OnUpdate(float deltaTime) {
        // 自定义更新逻辑
    }
}

// 优化:分时更新
public class TimedUpdateManager : MonoSingleton<TimedUpdateManager> {
    private Dictionary<float, List<Action>> timedUpdates = new Dictionary<float, List<Action>>();
    
    public void RegisterTimedUpdate(float interval, Action callback) {
        if (!timedUpdates.ContainsKey(interval)) {
            timedUpdates[interval] = new List<Action>();
            StartCoroutine(TimedUpdateCoroutine(interval));
        }
        
        timedUpdates[interval].Add(callback);
    }
    
    IEnumerator TimedUpdateCoroutine(float interval) {
        WaitForSeconds wait = new WaitForSeconds(interval);
        
        while (true) {
            yield return wait;
            
            if (timedUpdates.TryGetValue(interval, out List<Action> callbacks)) {
                foreach (var callback in callbacks) {
                    callback?.Invoke();
                }
            }
        }
    }
}

// 使用
public class Enemy : MonoBehaviour {
    void Start() {
        // 每秒更新一次AI(性能优化)
        TimedUpdateManager.Instance.RegisterTimedUpdate(1f, UpdateAI);
    }
    
    void UpdateAI() {
        // AI逻辑
    }
}

22. 脏标记模式(Dirty Flag) ⭐⭐⭐⭐
// 只在需要时才重新计算
public class Transform2D {
    private Vector2 localPosition;
    private float localRotation;
    private Vector2 localScale = Vector2.one;
    
    private Matrix3x3 localMatrix;
    private Matrix3x3 worldMatrix;
    
    private bool isLocalDirty = true;
    private bool isWorldDirty = true;
    
    private Transform2D parent;
    
    public Vector2 LocalPosition {
        get => localPosition;
        set {
            localPosition = value;
            SetDirty();
        }
    }
    
    public float LocalRotation {
        get => localRotation;
        set {
            localRotation = value;
            SetDirty();
        }
    }
    
    public Matrix3x3 WorldMatrix {
        get {
            if (isWorldDirty) {
                UpdateWorldMatrix();
            }
            return worldMatrix;
        }
    }
    
    private void SetDirty() {
        isLocalDirty = true;
        isWorldDirty = true;
        
        // 递归标记所有子节点为脏
        foreach (var child in GetChildren()) {
            child.SetDirty();
        }
    }
    
    private void UpdateWorldMatrix() {
        if (isLocalDirty) {
            UpdateLocalMatrix();
        }
        
        if (parent != null) {
            worldMatrix = parent.WorldMatrix * localMatrix;
        } else {
            worldMatrix = localMatrix;
        }
        
        isWorldDirty = false;
    }
    
    private void UpdateLocalMatrix() {
        // 计算本地矩阵(TRS)
        localMatrix = Matrix3x3.TRS(localPosition, localRotation, localScale);
        isLocalDirty = false;
    }
    
    private List<Transform2D> GetChildren() {
        return new List<Transform2D>();
    }
}

// Mesh合批优化使用脏标记
public class BatchRenderer : MonoBehaviour {
    private List<MeshData> meshes = new List<MeshData>();
    private Mesh combinedMesh;
    private bool isDirty = false;
    
    public void AddMesh(MeshData mesh) {
        meshes.Add(mesh);
        isDirty = true;
    }
    
    public void RemoveMesh(MeshData mesh) {
        meshes.Remove(mesh);
        isDirty = true;
    }
    
    void LateUpdate() {
        // 只在有修改时才重新合并Mesh
        if (isDirty) {
            RebuildCombinedMesh();
            isDirty = false;
        }
    }
    
    void RebuildCombinedMesh() {
        CombineInstance[] combines = new CombineInstance[meshes.Count];
        
        for (int i = 0; i < meshes.Count; i++) {
            combines[i].mesh = meshes[i].mesh;
            combines[i].transform = meshes[i].transform.localToWorldMatrix;
        }
        
        combinedMesh = new Mesh();
        combinedMesh.CombineMeshes(combines);
        
        GetComponent<MeshFilter>().mesh = combinedMesh;
    }
}

public class MeshData {
    public Mesh mesh;
    public Transform transform;
}

// 简单示例
public struct Matrix3x3 {
    public static Matrix3x3 TRS(Vector2 pos, float rot, Vector2 scale) {
        return new Matrix3x3();
    }
    
    public static Matrix3x3 operator *(Matrix3x3 a, Matrix3x3 b) {
        return new Matrix3x3();
    }
}

总结:以上一共22种设计模式,几乎涵盖了所有Unity的设计模式

✨随便写写

告别向来是悲情的。只要活着就无法避免悲伤,不过我们似乎更容易错过快乐。

by 马克·哈默

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值