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

Unity中如何通过字符串查找列表内的指定bool变量?

Unity 调试菜单暴露GameManager布尔变量实现方案

原有伪代码的核心问题

  • 强类型语法错误:C#是强类型语言,字符串变量myBoolName和bool类型完全独立,无法直接给字符串赋true/false的布尔值
  • 查找逻辑无效:遍历列表时判断「列表是否包含当前遍历元素」永远返回真,没有实现「按字符串匹配对应变量」的逻辑
  • 缺少映射关系:没有建立「变量名字符串」和「内存中实际bool字段」的关联,这是实现功能的核心缺失点

方案1:手动注册映射(新手首选,零复杂语法,稳定性最高)

这个方案不需要用到高级特性,逻辑完全可控,出问题极易排查,适合刚接触Unity开发的情况。

实现步骤

  1. 先做一个通用的调试Toggle UI预制体:基础Toggle组件+子节点文本组件,用来显示开关名
  2. 编写DebugMenu管理脚本,用字典存所有可调试bool的读写方法,注册时自动生成对应UI
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;

public class DebugMenu : MonoBehaviour
{
    public static DebugMenu Instance;
    // 存储结构:key=开关显示名,value=读值委托、写值委托
    private Dictionary<string, (Func<bool> GetVal, Action<bool> SetVal)> _boolDic = new();
    
    [Header("UI引用")]
    public Toggle togglePrefab;
    public Transform toggleRoot;

    private void Awake()
    {
        Instance = this;
    }

    /// <summary>
    /// 注册需要暴露到调试菜单的bool变量
    /// </summary>
    /// <param name="displayName">UI上显示的开关名,可以写中文方便非程序同事识别</param>
    /// <param name="getValue">读取当前bool值的方法</param>
    /// <param name="setValue">修改bool值的方法</param>
    public void RegisterBool(string displayName, Func<bool> getValue, Action<bool> setValue)
    {
        _boolDic[displayName] = (getValue, setValue);
        // 生成对应UI开关
        Toggle newToggle = Instantiate(togglePrefab, toggleRoot);
        newToggle.isOn = getValue.Invoke();
        newToggle.GetComponentInChildren<TMP_Text>().text = displayName;
        // 绑定UI事件:拖动开关时同步修改对应bool值
        newToggle.onValueChanged.AddListener((newVal) =>
        {
            setValue.Invoke(newVal);
        });
    }
}
  1. 在GameManager启动时,把所有需要暴露的bool手动注册到调试菜单即可
using UnityEngine;

public class GameManager : MonoBehaviour
{
    public static GameManager Instance;
    // 所有需要暴露的调试bool
    public bool isGodMode;
    public bool showFPS;
    public bool enemyCanAttack;
    public bool unlimitedAmmo;

    private void Awake()
    {
        Instance = this;
    }

    private void Start()
    {
        // 注册时第一个参数传UI显示名,支持中文
        DebugMenu.Instance.RegisterBool("无敌模式", () => isGodMode, val => isGodMode = val);
        DebugMenu.Instance.RegisterBool("显示FPS", () => showFPS, val => showFPS = val);
        DebugMenu.Instance.RegisterBool("敌人可攻击", () => enemyCanAttack, val => enemyCanAttack = val);
        DebugMenu.Instance.RegisterBool("无限弹药", () => unlimitedAmmo, val => unlimitedAmmo = val);
    }
}

方案优点

  • 没有复杂语法,逻辑完全透明,报错可以快速定位
  • 支持自定义中文显示名,不需要和代码里的变量名一致,非程序同事使用门槛低
  • 不会因为变量重命名、删除出现隐式报错

方案2:反射自动收集(无需手动注册,新增bool自动显示)

如果后续调试开关很多,不想每次新增变量都写注册代码,可以用C#反射特性,自动遍历GameManager的所有bool字段生成UI,适合对C#语法有基础了解后使用。

实现代码

把以下脚本挂在调试菜单对象上,拖好对应引用即可运行:

using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using UnityEngine.UI;
using TMPro;

public class AutoDebugMenu : MonoBehaviour
{
    [Header("目标引用")]
    public GameManager targetGameManager;
    public Toggle togglePrefab;
    public Transform toggleRoot;

    private Dictionary<FieldInfo, Toggle> _fieldToggleDic = new();

    private void Start()
    {
        // 自动获取GameManager上所有public的实例字段
        FieldInfo[] fields = typeof(GameManager).GetFields(BindingFlags.Public | BindingFlags.Instance);
        foreach (FieldInfo field in fields)
        {
            // 只筛选bool类型字段
            if (field.FieldType != typeof(bool)) continue;
            
            // 生成UI开关
            Toggle newToggle = Instantiate(togglePrefab, toggleRoot);
            bool currentVal = (bool)field.GetValue(targetGameManager);
            newToggle.isOn = currentVal;
            newToggle.GetComponentInChildren<TMP_Text>().text = field.Name;
            // 绑定值修改事件
            newToggle.onValueChanged.AddListener(newVal =>
            {
                field.SetValue(targetGameManager, newVal);
            });
            
            _fieldToggleDic.Add(field, newToggle);
        }
    }

    // 可选:如果代码里会动态修改bool值,加这段逻辑可以实时同步UI状态
    private void Update()
    {
        foreach (var pair in _fieldToggleDic)
        {
            bool currentVal = (bool)pair.Key.GetValue(targetGameManager);
            if (pair.Value.isOn != currentVal)
            {
                pair.Value.SetIsOnWithoutNotify(currentVal);
            }
        }
    }
}

注意事项

  • 默认只会收集public修饰的bool变量,如果需要收集私有变量,可以在GetFields参数里追加BindingFlags.NonPublic,但不建议调试项用私有字段
  • 可以给字段加[Tooltip("开关说明")]特性,反射时读取备注显示在UI上,降低使用门槛
  • 建议给调试菜单加快捷键呼出/隐藏逻辑(比如按F1切换菜单显隐),不影响正常游戏测试流程

内容的提问来源于stack exchange,提问作者Gael Fernandez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 16:06:26