You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于Enum实现类似《刺客信条:枭雄》的游戏升级系统

嘿,这个需求我熟!用Enum来实现《刺客信条:枭雄》那种线性解锁、部分升级会替换旧项的系统完全可行,而且逻辑清晰、容易维护。我来给你拆解具体的实现思路和代码示例~

实现思路核心

首先明确你的两个核心需求:

  1. 线性解锁:必须按顺序解锁前置升级才能购买后续项
  2. 升级替换/保留:同系列的升级(比如Scavenger I→II)会替换旧项,独立升级(比如Looter)则新增保留

我们可以用Enum定义所有升级项,再配合自定义Attribute存储升级元数据(比如所属组、前置条件、效果),最后用一个升级管理器类来处理解锁逻辑和状态跟踪。

具体实现步骤

1. 定义升级项Enum及元数据

首先用Enum列出所有升级项,然后通过自定义Attribute给每个升级项附加关键信息:所属组(用来区分替换关系)、前置升级、显示名称和效果。

自定义UpgradeInfoAttribute

这个Attribute用来给Enum字段添加元数据:

[AttributeUsage(AttributeTargets.Field)]
public class UpgradeInfoAttribute : Attribute
{
    public string DisplayName { get; } // 游戏内显示的名称
    public string UpgradeGroup { get; } // 所属升级组(同组替换)
    public UpgradeType? Prerequisite { get; } // 前置升级(可选)
    public string Effect { get; } // 升级效果描述

    public UpgradeInfoAttribute(string displayName, string upgradeGroup, string effect, UpgradeType? prerequisite = null)
    {
        DisplayName = displayName;
        UpgradeGroup = upgradeGroup;
        Effect = effect;
        Prerequisite = prerequisite;
    }
}

定义UpgradeType Enum

把你的升级项按需求分类,给每个项加上Attribute:

public enum UpgradeType
{
    [UpgradeInfo("Scavenger I", "Scavenger", "提升敌人掉落 loot 数量10%")]
    ScavengerI,

    [UpgradeInfo("Scavenger II", "Scavenger", "提升敌人掉落 loot 数量25%", UpgradeType.ScavengerI)]
    ScavengerII,

    [UpgradeInfo("Looter", "Looter", "无需开锁器即可开启稀有宝箱", UpgradeType.ScavengerII)]
    Looter,

    // 可以继续添加其他升级项示例
    [UpgradeInfo("开锁大师", "Lockpick", "减少开锁时间50%")]
    LockpickMaster,

    [UpgradeInfo("快速治疗 I", "QuickHeal", "减少治疗时间20%")]
    QuickHealI,

    [UpgradeInfo("快速治疗 II", "QuickHeal", "减少治疗时间40%", UpgradeType.QuickHealI)]
    QuickHealII
}

2. 实现升级管理器类

这个类负责跟踪升级状态、验证解锁条件、处理购买逻辑(替换/新增):

public class UpgradeManager
{
    // 存储当前生效的升级:key=升级组,value=当前激活的升级项
    private readonly Dictionary<string, UpgradeType> _activeUpgrades = new();
    // 存储所有已解锁的升级(包括被替换的,用来验证前置条件)
    private readonly HashSet<UpgradeType> _unlockedUpgrades = new();

    /// <summary>
    /// 检查是否满足解锁某个升级的条件
    /// </summary>
    public bool CanUnlockUpgrade(UpgradeType upgrade)
    {
        var upgradeInfo = GetUpgradeMetadata(upgrade);
        if (upgradeInfo == null) return false;

        // 有前置升级的话,必须已解锁前置
        if (upgradeInfo.Prerequisite.HasValue && !_unlockedUpgrades.Contains(upgradeInfo.Prerequisite.Value))
        {
            return false;
        }

        return true;
    }

    /// <summary>
    /// 购买升级,处理替换/新增逻辑
    /// </summary>
    public bool PurchaseUpgrade(UpgradeType upgrade)
    {
        if (!CanUnlockUpgrade(upgrade))
        {
            return false; // 不满足条件,购买失败
        }

        var upgradeInfo = GetUpgradeMetadata(upgrade);
        // 标记该升级为已解锁(即使被替换,也保留解锁记录)
        _unlockedUpgrades.Add(upgrade);

        // 处理同组替换逻辑
        if (!string.IsNullOrEmpty(upgradeInfo.UpgradeGroup))
        {
            if (_activeUpgrades.ContainsKey(upgradeInfo.UpgradeGroup))
            {
                // 替换同组旧升级,可以在这里添加旧效果移除的逻辑
                _activeUpgrades[upgradeInfo.UpgradeGroup] = upgrade;
            }
            else
            {
                // 新增升级组,添加到生效列表
                _activeUpgrades.Add(upgradeInfo.UpgradeGroup, upgrade);
            }
        }

        // 应用升级效果(比如修改玩家属性、解锁功能)
        ApplyUpgradeEffect(upgrade);
        return true;
    }

    /// <summary>
    /// 获取当前所有生效的升级
    /// </summary>
    public IEnumerable<UpgradeType> GetActiveUpgrades() => _activeUpgrades.Values;

    /// <summary>
    /// 获取升级的元数据
    /// </summary>
    private UpgradeInfoAttribute GetUpgradeMetadata(UpgradeType upgrade)
    {
        var field = typeof(UpgradeType).GetField(upgrade.ToString());
        return field?.GetCustomAttribute<UpgradeInfoAttribute>();
    }

    /// <summary>
    /// 应用升级效果的示例方法,根据实际需求扩展
    /// </summary>
    private void ApplyUpgradeEffect(UpgradeType upgrade)
    {
        switch (upgrade)
        {
            case UpgradeType.ScavengerI:
            case UpgradeType.ScavengerII:
                // 调整玩家的 loot 倍率
                break;
            case UpgradeType.Looter:
                // 解锁稀有宝箱的访问权限
                break;
            case UpgradeType.LockpickMaster:
                // 减少开锁时间
                break;
            // 其他升级的效果逻辑
        }
    }
}

3. 使用示例

// 初始化升级管理器
var upgradeManager = new UpgradeManager();

// 尝试直接买Scavenger II,没有前置Scavenger I,购买失败
bool boughtScavengerII = upgradeManager.PurchaseUpgrade(UpgradeType.ScavengerII); // 返回false

// 先买Scavenger I,成功
bool boughtScavengerI = upgradeManager.PurchaseUpgrade(UpgradeType.ScavengerI); // 返回true

// 再买Scavenger II,成功,此时Scavenger I被替换
boughtScavengerII = upgradeManager.PurchaseUpgrade(UpgradeType.ScavengerII); // 返回true

// 买Looter,需要Scavenger II已解锁,成功,新增到生效列表
bool boughtLooter = upgradeManager.PurchaseUpgrade(UpgradeType.Looter); // 返回true

// 获取当前生效的升级:Scavenger II、Looter
var activeUpgrades = upgradeManager.GetActiveUpgrades();
为什么这样实现?
  • 强类型安全:用Enum定义升级项,避免了字符串拼写错误,IDE还能自动补全
  • 逻辑清晰:升级的元数据(组、前置)和业务逻辑(解锁、替换)分离,后续新增升级只需要加Enum字段和Attribute,不用改管理器核心逻辑
  • 状态可控:用两个集合分别跟踪“已解锁”和“当前生效”的升级,既保证前置条件验证正确,又能精准控制当前生效的效果

内容的提问来源于stack exchange,提问作者Evie Frye

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:44:55