如何在C#(Unity)中结构化存储游戏关卡常量设置
如何在C#(Unity)中实现关卡固定设置的存储与动态访问
你想要的LevelSettings.Bar.{currentLevel}.Speed这种通过动态字符串直接访问静态类成员的语法,在C#中无法直接实现——因为C#是静态类型语言,编译时就需要确定成员名称。但可以通过以下几种方案实现类似的存储与访问效果:
方案一:类+字典存储(通用C#方案)
先定义单个关卡的配置类,再用字典把关卡名称和对应配置绑定,同时保留全局设置:
namespace LevelSettings { namespace Bar { // 单个关卡的配置结构 public class LevelConfig { public float Speed { get; } public string ActiveColor { get; } public string InactiveColor { get; } public LevelConfig(float speed, string activeColor, string inactiveColor) { Speed = speed; ActiveColor = activeColor; InactiveColor = inactiveColor; } } // 全局通用设置 public static int ExtraActiveBlocks = 3; // 存储所有关卡配置的字典,键为关卡名称 public static readonly Dictionary<string, LevelConfig> Levels = new Dictionary<string, LevelConfig> { {"Level1", new LevelConfig(0.6f, "red", "black")}, {"Level2", new LevelConfig(0.6f, "red", "black")}, {"Level3", new LevelConfig(0.6f, "red", "black")} }; } }
访问方式
string currentLevel = "Level1"; // 先校验关卡存在,避免抛出KeyNotFoundException if (LevelSettings.Bar.Levels.TryGetValue(currentLevel, out var levelConfig)) { float currentSpeed = levelConfig.Speed; string activeColor = levelConfig.ActiveColor; // 使用其他配置项... }
方案二:静态类嵌套+反射(不推荐频繁使用)
如果想接近你最初设想的静态类结构,可以用反射实现动态访问,但反射性能较差,不适合Unity运行时频繁调用:
namespace LevelSettings { namespace Bar { public static int ExtraActiveBlocks = 3; public static class Level1 { public static float Speed = 0.6f; public static string ActiveColor = "red"; public static string InactiveColor = "black"; } public static class Level2 { public static float Speed = 0.6f; public static string ActiveColor = "red"; public static string InactiveColor = "black"; } public static class Level3 { public static float Speed = 0.6f; public static string ActiveColor = "red"; public static string InactiveColor = "black"; } } }
访问方式
string currentLevel = "Level1"; // 获取对应静态类的Type对象,需要完整命名空间+类名 Type levelType = Type.GetType($"LevelSettings.Bar.{currentLevel}"); if (levelType != null) { // 反射获取字段值 float currentSpeed = (float)levelType.GetField("Speed").GetValue(null); string activeColor = (string)levelType.GetField("ActiveColor").GetValue(null); }
方案三:Unity ScriptableObject(Unity项目推荐)
这是Unity专属方案,支持可视化编辑配置,数据可序列化,无需硬编码,适合游戏开发场景:
using UnityEngine; using System.Collections.Generic; using System.Linq; namespace LevelSettings.Bar { // 单个关卡的配置资产 [CreateAssetMenu(fileName = "BarLevelConfig", menuName = "Level Settings/Bar Level Config")] public class LevelConfig : ScriptableObject { public float Speed = 0.6f; public string ActiveColor = "red"; public string InactiveColor = "black"; } // Bar模式的全局配置资产 [CreateAssetMenu(fileName = "BarGlobalSettings", menuName = "Level Settings/Bar Global Settings")] public class BarGlobalSettings : ScriptableObject { public int ExtraActiveBlocks = 3; // 用序列化的列表存储关卡名与配置的对应关系(Unity Inspector不直接支持字典) public List<LevelEntry> LevelEntries; [System.Serializable] public class LevelEntry { public string LevelName; public LevelConfig Config; } // 提供便捷的配置获取方法 public LevelConfig GetLevelConfig(string levelName) { return LevelEntries.FirstOrDefault(e => e.LevelName == levelName)?.Config; } } }
使用步骤
- 在Unity编辑器中右键创建
Level Settings/Bar Global Settings和Level Settings/Bar Level Config资产 - 在Global Settings资产中配置
ExtraActiveBlocks,并给每个关卡绑定对应的Level Config - 访问方式:
// 在脚本中通过Inspector引用全局配置资产 public BarGlobalSettings barGlobalSettings; void GetLevelSettings() { string currentLevel = "Level1"; var levelConfig = barGlobalSettings.GetLevelConfig(currentLevel); if (levelConfig != null) { float currentSpeed = levelConfig.Speed; // 使用其他配置项... } }
内容的提问来源于stack exchange,提问作者Zorgan
相关产品推荐
相关产品推荐

