- Home /
How To Make UI Button 2 Appear Three Seconds After UI Button 1 is pressed
Hi all,
I have 20 UI buttons that I need to appear one after other. The player pushes a button, it is destroyed and then so many seconds later another one appears, but only after the first one is destroyed. This process repeats for 20 buttons and then is looped. I have been using the included code to make the buttons appear after so many seconds. I'm wondering how to modify it so that it works as I described and then loops.
Thank you kindly in advance!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ButtonAppearance : MonoBehaviour
{
public GameObject Option_1;
public GameObject Option_2;
public GameObject Option_3;
public GameObject Option_4;
public GameObject Option_5;
public GameObject Option_6;
public GameObject Option_7;
public GameObject Option_8;
public GameObject Option_9;
public GameObject Option_10;
// Use this for initialization
void Start()
{
StartCoroutine(HideAndShow(Option_1, 3.0f));
StartCoroutine(HideAndShow(Option_2, 7.0f));
StartCoroutine(HideAndShow(Option_3, 11.0f));
StartCoroutine(HideAndShow(Option_4, 15.0f));
StartCoroutine(HideAndShow(Option_5, 19.0f));
StartCoroutine(HideAndShow(Option_6, 23.0f));
StartCoroutine(HideAndShow(Option_7, 27.0f));
StartCoroutine(HideAndShow(Option_8, 31.0f));
StartCoroutine(HideAndShow(Option_9, 35.0f));
StartCoroutine(HideAndShow(Option_10, 39.0f));
}
// Update is called once per frame
void Update()
{
}
IEnumerator HideAndShow(GameObject Option, float delay)
{
Option.SetActive(false);
yield return new WaitForSeconds(delay);
Option.SetActive(true);
}
}
Answer by Hellium · Feb 13, 2021 at 10:04 PM
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
public class ButtonAppearance : MonoBehaviour
{
// Fill the values in the inspector
public DelayedButton[] DelayedButtons;
void Start()
{
for(int i = 0 ; i < DelayedButtons.Length ; ++i)
{
DelayedButton nextButton = DelayedButtons[(i +1) % DelayedButtons.Length];
DelayedButtons[i].ActiveGameObjectAfterDelayUponClick(nextButton, this);
if (i > 0)
DelayedButtons[i].DisableButtonObject();
}
DelayedButtons[0].ActiveGameObjectAfterDelay(DelayedButtons[0], this);
}
}
[System.Serializable]
public class DelayedButton
{
[SerializeField] private Button button;
[SerializeField, Min(0)] private float delay;
public void DisableButtonObject()
{
button.gameObject.SetActive(false);
}
public void ActiveGameObjectAfterDelayUponClick(DelayedButton nextButton, MonoBehaviour monoBehaviour)
{
button.onClick.AddListener(() => ActiveGameObjectAfterDelay(nextButton, monoBehaviour));
}
public void ActiveGameObjectAfterDelay(DelayedButton nextButton, MonoBehaviour monoBehaviour)
{
DisableButtonObject();
monoBehaviour.StartCoroutine(ActiveGameObjectAfterDelayCoroutine(nextButton.button.gameObject, nextButton.delay));
}
private IEnumerator ActiveGameObjectAfterDelayCoroutine(GameObject gameObject, float delay)
{
yield return new WaitForSeconds(delay);
gameObject.SetActive(true);
}
}
Thank you @Hellium ! This worked perfectly for me and is a very elegant solution. I've been learning a lot from your answers too as a bonus.
Thanks again @Hellium your script works great. I've been tinkering with it trying to make the first button have a delay the first time the game is run. As of now it appears immediately and only has a delay once the loop is complete. I tried putting the whole thing into a coroutine but it didn't work great. Any advice on how to delay that first button the first time the script is run? aka delay the script from running say 3 seconds from the game opening?
Appreciate your time and valuable insight.
I've edited the code to take into account your new request. /!\ Both classes have changed.
Thanks for the speedy reply and edit! I'm unfortunately getting an error on line 19:
:Assets\Scripts\ButtonAppearance.cs(19,9): error CS0103: The name 'ActiveGameObjectAfterDelay' does not exist in the current context
I'm sure its straightforward, but googling that error hasn't led me to any fixes yet.
Hi again @Hellium. I've noticed one strange thing where if there is more than 9 delayed buttons running in the game, the buttons start appearing two at a time. Anything in the code come to $$anonymous$$d that could be causing this? Thank you in advance!
Can you show the values you've set in the inspector? I can't reproduce the problem with 15 buttons and delays from .5 to 7.5 seconds.
Turns out it was totally my mistake! I had copied the same button in multiple slots in the Inspector and that was causing multiple buttons to be displayed. Thank you for trying to replicate the problem.
Hi again @Helium thanks once again for helping me with this problem. Could you highlight which part of the script causes the script to loop back to the first button once it is finished? I'm curious how that part functions for future use on other scripts. Thanks.
DelayedButton nextButton = DelayedButtons[(i +1) % DelayedButtons.Length];
when i = DelayedButtons.Length - 1
(last element of the array)
i + 1 = DelayedButtons.Length
(i + 1) % DelayedButtons.Length = 0
(first element of the array)
Perfect info. That's really helpful thank you. Sorry this is co$$anonymous$$g piece by piece but this should be the final piece of the puzzle. I am trying to make the whole process stop/start by pressing a button. Is there a way to do that within the code? Or should I just look into deactivating the whole script when a button is onClick.
Thank you, totally understand if this is outside the scope of the question and I should look elsewhere.
Your answer
Follow this Question
Related Questions
WaitForSeconds bug,Coroutine Bug 1 Answer
Sequentially wait for multiple coroutines to finish 0 Answers
Looping a Script 2 Answers
Yield WaitForSeconds Not Working. Coroutine. 1 Answer
How to make WaitForSeconds work as a repeating/looping timer? 1 Answer