There are a few things you can do to achieve this. Your current code is never toggling the bool pressed
. You can just catch the unwanted button presses with a localized bool like you are doing now, but there might be a better approach.
I would consider changing the intractability of the button to also show the end-user that they can not press the button for a short amount of time.
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;
}
Assign the button in the editor to btn
and set whatever time you want to wait between button presses for timeToWait
. You will also need to assign the button's OnClick
to ClickButton
, either in code or in the inspector. With this solution the function will not be able to be called as the button itself will be grayed out and not be able to be clicked. After the timeToWait
duration is over, the button will reactivate. Place whatever other code you need in the ClickButton
method that drives your quote cycling.
Edit: Here is similar code but using an Invoke
instead of Coroutine
as requested
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;
}
Edit 2: There are a few ways you can go about having one button disable all four buttons. In general practice, you do not want these buttons knowing about each other, so it would be a good idea to make a button manager that handles the OnClick
now and sends the event to all Buttons
it knows about.
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;
}
}
Let me know if you have issues with this.