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

Unity游戏Mod按钮按布尔值切换文本颜色时遇空引用异常求助

问题:Unity Mod GUI按钮样式引发NullReferenceException异常

我正在为一款游戏Mod开发简单的2D GUI,通过按钮启用/禁用Mod功能。目前点击按钮时,文本会在“功能:关闭”和“功能:开启”间切换,这是通过布尔值实现的。为了让用户更清晰区分功能状态,我尝试同时修改按钮文本颜色。

已尝试的方法

通过资料了解到可通过GUIStyle修改按钮文本颜色,代码如下:

private static GUIStyle enabledText;
private static GUIStyle disabledText;

public static void Start()
{
    enabledText = new GUIStyle(GUI.skin.button);
    enabledText.normal.textColor = Color.green;

    disabledText = new GUIStyle(GUI.skin.button);
    disabledText.normal.textColor = Color.red;
}

使用时通过GUILayout.Button("Label", style);传入样式。

按钮实现示例

if (GUILayout.Button("God Mode: " + (s_isGodMode ? "On" : "Off")))
{
    s_isGodMode = !s_isGodMode;
}

结合后的代码(出现问题的版本)

if (GUILayout.Button("God Mode: " + (s_isGodMode ? "On" : "Off"), (s_isGodMode ? enabledText : disabledText)))
{
    s_isGodMode = !s_isGodMode;
}

这段代码编译无错误或警告,但加载时出现NullReferenceException异常,菜单仅显示空白矩形,移除样式参数后功能恢复正常。


问题原因

空引用异常的核心原因是静态的Start方法不会被Unity自动调用。Unity的生命周期方法(比如Start、Awake)只有非静态的实例方法才会被引擎识别并执行,静态的Start方法完全不会触发,导致enabledText和disabledText两个变量始终为null,传入GUILayout.Button时自然抛出空引用异常。

解决方案

方案1:将Start方法改为非静态

去掉Start方法的static修饰符,让Unity能自动调用它初始化样式:

private static GUIStyle enabledText;
private static GUIStyle disabledText;

// 移除static,让Unity自动执行初始化
public void Start()
{
    enabledText = new GUIStyle(GUI.skin.button);
    enabledText.normal.textColor = Color.green;

    disabledText = new GUIStyle(GUI.skin.button);
    disabledText.normal.textColor = Color.red;
}

方案2:在GUI绘制时懒加载样式

如果你的Mod代码是静态类结构,无法使用非静态生命周期方法,可以在OnGUI方法里先检查样式是否初始化,未初始化就创建:

private static GUIStyle enabledText;
private static GUIStyle disabledText;
private static bool s_isGodMode;

public static void OnGUI()
{
    // 懒加载样式,避免空引用
    if (enabledText == null)
    {
        enabledText = new GUIStyle(GUI.skin.button);
        enabledText.normal.textColor = Color.green;
    }
    if (disabledText == null)
    {
        disabledText = new GUIStyle(GUI.skin.button);
        disabledText.normal.textColor = Color.red;
    }

    // 绘制按钮
    if (GUILayout.Button("God Mode: " + (s_isGodMode ? "On" : "Off"), s_isGodMode ? enabledText : disabledText))
    {
        s_isGodMode = !s_isGodMode;
    }
}

方案3:优化为单一样式动态修改颜色

可以只创建一个GUIStyle实例,每次绘制时根据状态修改文本颜色,减少资源占用:

private static GUIStyle buttonStyle;
private static bool s_isGodMode;

public static void OnGUI()
{
    if (buttonStyle == null)
    {
        buttonStyle = new GUIStyle(GUI.skin.button);
    }

    // 根据功能状态动态切换文本颜色
    buttonStyle.normal.textColor = s_isGodMode ? Color.green : Color.red;

    if (GUILayout.Button("God Mode: " + (s_isGodMode ? "On" : "Off"), buttonStyle))
    {
        s_isGodMode = !s_isGodMode;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 12:50:45