You need to enable JavaScript to run this app. Unity C# 如何实现变量注册,让MyManager在Update中实时管控变量
优惠活动
大模型
产品
解决方案
定价
更多

Unity C# 如何实现变量注册,让MyManager在Update中实时管控变量

跨脚本实时变量控制功能实现方案

核心前置注意事项

C#的值类型(float、int、bool等)默认是按值传递的,如果直接把leftTime作为参数传入注册方法,MyManager内部只会拿到一个变量值的独立副本,后续对副本的所有修改都不会影响原脚本里的原始变量。
C#语言层面不支持将方法栈上的值类型引用直接传入lambda表达式捕获,因此无法实现无额外参数的RegisterVariable(leftTime)调用形式,通过传入变量读写逻辑的绑定方式,是兼顾简洁性和运行性能的通用方案,不会产生反射、表达式树解析的额外开销。

第一步:实现MyManager核心逻辑

MyManager采用Unity单例模式挂载到场景中,自带Update生命周期,负责所有已注册变量的实时控制:

public class MyManager : MonoBehaviour
{
    // 全局单例访问入口
    public static MyManager Instance { get; private set; }

    // 统一存储所有已注册变量的非泛型接口
    private interface IVariableBinding { }
    // 泛型绑定类,存储单种类型变量的访问逻辑
    private class VariableBinding<T> : IVariableBinding
    {
        public Func<T> ValueGetter;
        public Action<T> ValueSetter;
    }
    // 所有已注册变量的存储集合
    private readonly List<IVariableBinding> _bindingList = new List<IVariableBinding>();

    private void Awake()
    {
        // 单例初始化逻辑,避免重复实例
        if (Instance != null && Instance != this)
        {
            Destroy(gameObject);
            return;
        }
        Instance = this;
        // 跨场景不销毁,保证全局可访问
        DontDestroyOnLoad(gameObject);
    }

    /// <summary>
    /// 变量注册方法,建立MyManager和原脚本变量的双向绑定
    /// </summary>
    /// <param name="getter">读取原变量的逻辑</param>
    /// <param name="setter">写入原变量的逻辑</param>
    public void RegisterVariable<T>(Func<T> getter, Action<T> setter)
    {
        // 入参合法性校验,避免空引用
        if (getter == null || setter == null) return;
        var binding = new VariableBinding<T>
        {
            ValueGetter = getter,
            ValueSetter = setter
        };
        _bindingList.Add(binding);
    }

    private void Update()
    {
        // 遍历所有已注册变量,执行实时控制逻辑
        foreach (var binding in _bindingList)
        {
            // 针对不同类型的注册变量,分别写对应的控制规则
            switch (binding)
            {
                // 示例:对所有注册的float类型变量做倒计时控制
                case VariableBinding<float> floatBinding:
                {
                    float currentValue = floatBinding.ValueGetter();
                    // 每帧减去帧间隔时间,实现实时同步到原变量
                    floatBinding.ValueSetter(currentValue - Time.deltaTime);
                    break;
                }
                // 可扩展其他类型的控制逻辑:比如int变量的数值钳制、bool变量的状态切换等
            }
        }
    }
}

第二步:业务脚本侧的注册调用

在需要绑定变量的业务脚本初始化阶段完成注册:

public class CountdownScript : MonoBehaviour
{
    // 原脚本定义的控制变量
    public float leftTime = 10f;

    private void Start()
    {
        // 注册变量到MyManager,绑定读写逻辑
        MyManager.Instance.RegisterVariable(
            getter: () => leftTime,
            setter: (newValue) => leftTime = newValue
        );
    }
}

可扩展优化点

  • 给每个绑定增加唯一标识,支持UnregisterVariable方法,在场景卸载、脚本销毁时移除无效绑定,避免空引用报错
  • 增加变量值变更的事件回调,方便其他脚本(比如UI)实时监听被控制的变量值变化
  • 支持给绑定增加标签过滤逻辑,比如只对绑定了"countdown"标签的变量做倒计时,避免不同用途的变量被统一控制

内容的提问来源于stack exchange,提问作者Maruf Artukoğlu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.09 15:27:01