【问题标题】:Hide and show a button in Unity (C#)在 Unity (C#) 中隐藏和显示按钮
【发布时间】:2021-01-11 23:23:24
【问题描述】:

我有一个按钮(在 UI 中),有时我想隐藏它(但稍后再显示),这意味着它不应该再显示并且我不应该能够点击它。我找到的唯一解决方案(实际上设法隐藏了按钮)是SetActive()

但是在Update() 中,当我执行SetActive(false) 时(真/假由我脚本中的变量wave_happening 控制),Update() 不再运行,所以我无法将其设置为再次真实。 当我在另一个脚本中执行GameObject.Find("Start Button").SetActive(true) 时,它只会给我一个 NullReferenceException(对象引用未设置为对象的实例)。

这是我的Update() 函数:

void Update() {
    wave_happening = enemy_spawner_script.wave_happening;
    Debug.Log(wave_happening);
    transform.gameObject.SetActive(wave_happening);
}

是否有解决此问题的解决方案,或隐藏按钮的其他方法?

我对 Unity 和 C# 还很陌生,所以我不太了解。

【问题讨论】:

  • 您可以通过禁用按钮的图像来隐藏按钮!
  • 你不能通过另一种保持启用的管理器脚本来控制它吗?例如。在您更改 enemy_spawner_script.wave_happening 的同一时刻
  • @JaysmitoMukherjee 您还需要禁用功能...您可以单击空白处,它会带您进入菜单:P
  • 一般来说这应该是基于事件的,而不是每帧轮询检查一个布尔标志...
  • 禁用图像确实不是解决方案伙计们(也可能是文本 - 以及其他问题)

标签: c# unity3d button


【解决方案1】:

您可以尝试禁用按钮的呈现和功能组件:

GetComponent<Button>().enabled = false; // remove functionality

GetComponent<Image>().enabled = false; // remove rendering

现在,将其添加到您的更新功能,加上一些性能更改,这样您就不会仅在需要时启用/禁用每一帧:

private bool isShowing = true; // or whatever your default value is

void Update() {
    wave_happening = enemy_spawner_script.wave_happening;
    Debug.Log(wave_happening);
    
    if(wave_happening != isShowing) {
        show(wave_happening);
        isShowing = wave_happening;
    }
}

void show(bool isShow) {
    GetComponent<Button>().enabled = isShow; // remove functionality

    GetComponent<Image>().enabled = isShow; // remove rendering
}

【讨论】:

  • 我不能在组件上使用SetActive(),只能在游戏对象上使用。
  • 对不起,不小心写错了……:(应该启用
  • 顺便说一句,您可以完全省略 transform.gameObject 访问
  • @Whitespace ,最简单最可靠的一步就是canvasGroup.alpha = wave_happening ? 1f : 0f;
【解决方案2】:

要做好这件事真的很难。出现了很多问题:

  • 按钮不可避免地会在 H 或 V 布局组中,作为一个基本的软件工程问题,无论它是否在布局组中,您当然希望它能够工作,因为该布局细节可能会被您更改设计师随着项目的进行。出于这个原因,正如 OP 最初猜测的那样,简单地使用 .SetActive

  • 但是你遇到了按钮关闭的问题,所以Update 没有运行。一个简单的解决方案是将按钮放入包装器中。也就是说,只是在一个 UI 中Panel。将按钮管理器脚本放在包装器上,而不是放在按钮本身上。

那么你就在管理器脚本上有一个漂亮的属性,

public bool Showme
{
    etc...

然后你就可以走了……

void Update()
{
    Showme = enemy_spawner_script.wave_happening;
}

无法获得看起来更简单的代码。

  • 但是,如果您使用包装面板。确实,您必须非常擅长使用 UI(尤其是自动调整大小的东西)才能使其按照您想要的方式工作。但是,不幸的是,这是构建 Unity 专业知识的一部分。 :/

  • 对性能的担忧……真的很荒谬。 Unity 的原始代码“检查布尔值”和您自己的“检查布尔值”没有区别。但是,可以肯定的是,在更新中轮询它是一种风格问题。 (请注意,在上面的“B”点中,如果您要使用极其丑陋的“反轮询”代码,请将其埋在该属性中。)

然后……

“诡计”解决方案

  • Unity UI 中的一个提示是您可以在任何地方添加CanvasGroup。你为什么要这样做?它使您可以淡化整个事物,这通常是实现您想要的快速解决方案。

因此..

public CanvasGroup fader;

然后..

void Update()
{
    fader.alpha = enemy_spawner_script.wave_happening ? 1f : 0f;
}

你就完成了!

【讨论】:

  • 那个编辑更清晰了,谢谢。
  • 绝对很难找到一个词来表达“这是一个让你看起来很聪明的棘手动作之一,但实际上它只是一种糟糕的工程,不应该如果 Unity 不是毫无头绪的下降,那就没有必要了”:/
  • 解决 Unity 不足的占位符解决方案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-05
  • 1970-01-01
  • 1970-01-01
  • 2017-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多