Unity中如何将变量引用存储到另一个变量(命令系统需求)
在Unity中实现基于变量引用的命令系统
C#不像C那样支持裸指针(虽然有unsafe上下文的指针,但Unity中不推荐使用,还需要额外配置),但可以通过自定义包装类或委托实现类似的“变量引用”效果,直接修改分散在不同脚本中的原变量,不用写大量switch case。
核心实现思路:用泛型包装类捕获变量的读写逻辑
我们可以定义一个泛型类,通过委托捕获目标变量的get和set方法,这样存储的包装类实例就相当于对原变量的“引用”,修改包装类的Value属性时会直接作用到原变量上。
1. 定义泛型变量引用类
public class VariableRef<T> { private readonly Func<T> _getter; private readonly Action<T> _setter; public VariableRef(Func<T> getter, Action<T> setter) { _getter = getter; _setter = setter; } // 通过这个属性读写原变量 public T Value { get => _getter(); set => _setter(value); } }
2. 构建变量映射数组(或字典)
按照你想要的数组方式,把命令字符串和对应的变量引用绑定起来:
// 模拟控制台输入的参数和新值 string argument = "player.health"; int newValue = 100; // 命令字符串数组 string[] lookup = { "player.health", "a.second.variable", "a.third.variable" }; // 对应变量的引用数组(这里以int类型为例,其他类型可以用对应的VariableRef<T>) VariableRef<int>[] variableRefs = new[] { new VariableRef<int>(() => playerController.health, val => playerController.health = val), new VariableRef<int>(() => some.other.variable, val => some.other.variable = val), new VariableRef<int>(() => another.variable, val => another.variable = val) };
3. 处理命令并修改变量
遍历数组匹配命令,找到后直接修改原变量:
for (int i = 0; i < lookup.Length; i++) { if (lookup[i] == argument) { variableRefs[i].Value = newValue; break; // 找到后立即退出循环,提升效率 } }
优化方案:用字典替代数组(更高效)
如果变量数量较多,数组遍历的效率是O(n),换成字典可以做到O(1)的查找效率,和你提到的“用多个字典管理游戏值”的思路契合:
// 构建命令-变量引用字典 var variableMap = new Dictionary<string, VariableRef<int>> { { "player.health", new VariableRef<int>(() => playerController.health, val => playerController.health = val) }, { "a.second.variable", new VariableRef<int>(() => some.other.variable, val => some.other.variable = val) }, { "a.third.variable", new VariableRef<int>(() => another.variable, val => another.variable = val) } }; // 处理命令 if (variableMap.TryGetValue(argument, out var targetVar)) { targetVar.Value = newValue; }
支持多类型变量
如果需要修改不同类型的变量(比如int、float、bool),可以分类型管理字典,或者用一个包含类型信息的结构,例如:
// 存储不同类型的变量引用 var intVars = new Dictionary<string, VariableRef<int>>(); var floatVars = new Dictionary<string, VariableRef<float>>(); // 处理命令时,先解析输入值的类型,再对应到相应的字典 // 比如输入"ModVal set player.health 100",解析出值是int,就去intVars查找
关于C#的指针
C#确实支持unsafe指针,但需要在Unity的PlayerSettings中开启“Allow unsafe code”选项,且只能用于值类型,还会带来内存安全风险,不推荐在游戏业务逻辑中使用,上面的包装类方法更安全、更符合C#的设计规范。
内容的提问来源于stack exchange,提问作者Ezreal
相关产品推荐
相关产品推荐

