如何解决在 Unity 中每隔几秒钟只使用一次按钮
我正在尝试使 Unity 中的按钮只能每隔几秒钟按下和激活一次。我有一个带有名言的数组,当我按下按钮时,它会显示这些名言,但是如果您连续按下按钮,它将循环浏览所有名言,而无法深思熟虑并通读它们。现在,我尝试过类似下面的操作,但它什么也没做(因为按钮仍然可以被按下并且没有明显的效果):
Bool pressed;
void Function () {
if (pressed) {
//code to call array
}
}
我认为 bool 和 if 循环的简单组合就足够了,但这行不通。我接近这个概念吗?需要进行哪些更改才能使其正常运行?
解决方法
您可以采取一些措施来实现这一目标。您当前的代码永远不会切换 bool pressed
。您可以像现在一样使用本地化的 bool 来捕捉不需要的按钮按下,但可能有更好的方法。
我会考虑改变按钮的难处理性,以向最终用户表明他们无法在短时间内按下按钮。
using UnityEngine.UI;
// button that will be pressed
[SerializeField] private Button btn = null;
// time until the button is re-enabled after being pressed
private float timeToWait = 5f;
// reference to the coroutine that toggles our button
private Coroutine buttonDisabled = null;
private void Start()
{
// you can either add the OnClick in the inspector,or you can programmatically add it here
btn.onClick.AddListener(ClickButton);
}
public void ClickButton()
{
// if we have an ongoing coroutine do not start another
if(buttonDisabled != null)
return;
// start our coroutine to re-enable the button
buttonDisabled = StartCoroutine(DisableButtonForSeconds(timeToWait));
// put any other code needed here such as displaying a new quote
}
private IEnumerator DisableButtonForSeconds(float seconds)
{
// disable the button
btn.interactable = false;
// wait for our amount of time to re-enable
yield return new WaitForSeconds(seconds);
// re-enable the button
btn.interactable = true;
// reset our reference to be called again
buttonDisabled = null;
}
将编辑器中的按钮分配给 btn
并设置您想要在按钮按下之间等待 timeToWait
的任何时间。您还需要在代码或检查器中将按钮的 OnClick
分配给 ClickButton
。使用此解决方案,将无法调用该函数,因为按钮本身将变灰且无法单击。 timeToWait
持续时间结束后,按钮将重新激活。将您需要的任何其他代码放入 ClickButton
方法中,以驱动您的报价循环。
编辑:这里是类似的代码,但按照要求使用 Invoke
而不是 Coroutine
using UnityEngine.UI;
// button that will be pressed
[SerializeField] private Button btn = null;
// time until the button is re-enabled after being pressed
private float timeToWait = 5f;
private void Start()
{
// you can either add the OnClick in the inspector,or you can programmatically add it here
btn.onClick.AddListener(ClickButton);
}
public void ClickButton()
{
// do not start the function if we are already in the process
if (IsInvoking("ReEnableButton"))
return;
// disable our button interactability
btn.interactable = false;
// call our function ReenableButton in timeToWait seconds
Invoke("ReEnableButton",timeToWait);
}
private void ReEnableButton()
{
// re-enable the button
btn.interactable = true;
}
编辑 2:有几种方法可以让一个按钮禁用所有四个按钮。在一般实践中,您不希望这些按钮相互了解,因此最好制作一个按钮管理器来处理 OnClick
并将事件发送给它知道的所有 Buttons
.
using UnityEngine.UI;
public class ButtonManager : MonoBehaviour
{
// assign these button references in the inspector by dragging them into the list
[SerializeField] private List<YourButtonScript> YourButtons = new List<YourButtonScript>();
private void Start()
{
// assign the onClick of each button here INSTEAD of the Start() in the button class
// you can still have an onClick in the Button itself,but do NOT have it do the disabling
foreach(YourButtonScript btn in YourButtons)
{
// assign our onClick to callback to disable all buttons
btn.SetDisableOnclick(DisableAllButtons);
}
}
public void DisableAllButtons()
{
foreach(YourButtonScript btn in YourButtons)
btn.DisableButton();
}
}
public class YourButtonScript : MonoBehaviour
{
using UnityEngine.UI;
// button that will be pressed
[SerializeField] private Button btn = null;
// time until the button is re-enabled after being pressed
private float timeToWait = 5f;
// reference to the coroutine that toggles our button
private Coroutine buttonDisabled = null;
public delegate void DisableButtonCallback();
public void SetDisableOnclick(DisableButtonCallback callback)
{
// add the callback to the manager
btn.onClick.AddListener(delegate{callback();});
}
private void Start()
{
// do NOT call the ClickButton anymore from here as the manager handles it
// if you have other button specific data put it in HandleSpecificButtonQuoteData() now
btn.onClick.AddListener(HandleSpecificButtonQuoteData);
}
private void HandleSpecificButtonQuoteData()
{
// put whatever code here that is specific to JUST this button
// if it handles the quotes or what not,display it here
}
public void DisableButton()
{
// if we have an ongoing coroutine do not start another
if(buttonDisabled != null)
return;
// start our coroutine to re-enable the button
buttonDisabled = StartCoroutine(DisableButtonForSeconds(timeToWait));
}
private IEnumerator DisableButtonForSeconds(float seconds)
{
// disable the button
btn.interactable = false;
// wait for our amount of time to re-enable
yield return new WaitForSeconds(seconds);
// re-enable the button
btn.interactable = true;
// reset our reference to be called again
buttonDisabled = null;
}
}
如果您对此有任何疑问,请告诉我。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。