[英]Hide and show a button in Unity (C#)
I have a button (in UI), that I want to hide sometimes (but show again later), which means that it shouldn't show anymore and I shouldn't be able to click it.我有一个按钮(在 UI 中),有时我想隐藏它(但稍后再显示),这意味着它不应该再显示并且我不应该能够单击它。 The only solution I found (that has actually managed to hide the button), is
SetActive()
.我找到的唯一解决方案(实际上已经设法隐藏了按钮)是
SetActive()
。
But in Update()
, when I do SetActive(false)
(the true/false is controlled with the variable wave_happening
in my script), Update()
doesn't run anymore, so I can't set it to true again.但是在
Update()
中,当我执行SetActive(false)
(真/假由脚本中的变量wave_happening
控制)时, Update()
不再运行,因此我无法再次将其设置为 true。 When I do GameObject.Find("Start Button").SetActive(true)
in another script, it just gives me a NullReferenceException (Object reference not set to an instance of an object).当我在另一个脚本中执行
GameObject.Find("Start Button").SetActive(true)
时,它只会给我一个 NullReferenceException (对象引用未设置为对象的实例)。
This is my Update()
function:这是我的
Update()
function:
void Update() {
wave_happening = enemy_spawner_script.wave_happening;
Debug.Log(wave_happening);
transform.gameObject.SetActive(wave_happening);
}
Is there a solution to stop this problem, or another way to hide a button?是否有解决此问题的解决方案,或其他隐藏按钮的方法?
I'm fairly new to Unity and C#, so I don't know very much.我对 Unity 和 C# 还很陌生,所以我不太了解。
You can try disabling the button's rendering and functionality components:您可以尝试禁用按钮的呈现和功能组件:
GetComponent<Button>().enabled = false; // remove functionality
GetComponent<Image>().enabled = false; // remove rendering
Now, adding that to your Update function, plus a few changes for performance so you are not enabling/disabling every single frame, only when needed:现在,将其添加到您的更新 function 中,加上一些性能更改,因此您不会仅在需要时启用/禁用每一帧:
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
}
It's really difficult to do this well.要做好这件事真的很难。 Lots of issues arise:
会出现很多问题:
Inevitably the button will be in a H or V layout group, and, as a basic software engineering issue of course you want it to work whether or not it is in a layout group, as that layout detail may be changed by your designers as the project goes on.不可避免地,按钮将位于 H 或 V 布局组中,并且,作为一个基本的软件工程问题,您当然希望它无论是否在布局组中都能正常工作,因为您的设计师可能会更改布局细节作为项目继续进行。 For this reason it is a really good idea, as the OP initially guessed, to simply use
.SetActive
出于这个原因,正如 OP 最初猜测的那样,简单地使用
.SetActive
是一个非常好的主意
But then you have the problem of the button being off so Update
is not running.但是你遇到了按钮关闭的问题,因此
Update
没有运行。 A simple solution is just to put the button in a wrapper.一个简单的解决方案是将按钮放入包装器中。 That is to say, simply in a UI
Panel
.也就是说,只是在一个 UI
Panel
中。 Have the button manager script on that wrapper rather than on the button per se.在该包装器上而不是在按钮本身上拥有按钮管理器脚本。
Then you just have a pretty Property on the manager script,然后你在管理器脚本上有一个漂亮的属性,
public bool Showme
{
etc...
and then you can just go...然后你就可以 go ...
void Update()
{
Showme = enemy_spawner_script.wave_happening;
}
Can't get simpler looking code.无法获得更简单的代码。
However, if you use a wrapper Panel.但是,如果您使用包装面板。 It is true that you have to be pretty expert at using the UI (particularly the auto sizing stuff) to make it work just the way you want.
确实,您必须非常擅长使用 UI(尤其是自动调整大小的东西)才能使其按照您想要的方式工作。 But, that's part of building Unity expertise unfortunately.
但是,不幸的是,这是构建 Unity 专业知识的一部分。 :/
:/
The concerns about performance is... truly ridiculous.对性能的担忧……真的很荒谬。 There's no difference between Unity's raw code "checking a boolean" and yourself "checking a boolean".
Unity 的原始代码“检查布尔值”和您自己的“检查布尔值”没有区别。 However for sure as a matter of style it's crap to poll it in Update.
但是,可以肯定的是,在更新中轮询它是一种风格问题。 (Note that in point "B" just above, if you're going to have heinously ugly "anti-polling" code, bury it in that Property.)
(请注意,在上面的“B”点中,如果您要使用极其丑陋的“反轮询”代码,请将其埋在该属性中。)
And then...接着...
CanvasGroup
anywhere. CanvasGroup
。 Why would you do this? Hence..因此..
public CanvasGroup fader;
and then..接着..
void Update()
{
fader.alpha = enemy_spawner_script.wave_happening ? 1f : 0f;
}
and you're done!你就完成了!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.