Hi, I’m looking for buttons that can be clickable multiple times.
For example;
click on next button: runs script A
click on same next button: runs script B
click on same next button : runs script C
Here’s my code, but it only works with next button. I also need to multiple clickable back button on this code.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class NextBackButton: MonoBehaviour
{
public apPortrait portrait;
private int currentOption = 0;
[SerializeField] private Button previousButton;
[SerializeField] private Button nextButton;
public void RunCode0()
{
//Do something
}
public void RunCode1()
{
//Do something
}
public void RunCode2()
{
//Do something
}
public void RunCode3()
{
//Do something
}
private void Start()
{
// set the initial text of the button
//setButtonText(currentOption);
// add an event listener to look out for button clicks
nextButton.onClick.AddListener(myButtonClick);
}
public void myButtonClick()
{
switch (currentOption)
{
case 0:
// run stuff for option 1
RunCode0();
// change the current option for the next click
currentOption = 1;
// change the text on the button to be the next option
//setButtonText(currentOption);
break;
case 1:
Debug.Log("Doing option 2 things");
RunCode1();
// change the current option for the next click
if(nextButton.interactable)
{
currentOption = 2;
}
else if(previousButton.interactable)
{
currentOption = 0;
}
//setButtonText(currentOption);
break;
case 2:
Debug.Log("Doing option 3 things");
RunCode2();
// change the current option for the next click
if (nextButton.interactable)
{
currentOption = 3;
}
else if (previousButton.interactable)
{
currentOption = 1;
}
//setButtonText(currentOption);
break;
case 3:
Debug.Log("Doing option 4 things");
RunCode3();
// change the current option for the next click
if (nextButton.interactable)
{
currentOption = 4;
}
else if (previousButton.interactable)
{
currentOption = 2;
}
//setButtonText(currentOption);
break;
}
}
void setButtonText(string buttonText)
{
nextButton.transform.GetChild(0).GetComponent<Text>().text = buttonText;
}
}
Change your myButtonClick() to myButtonClick(int n). When in the On Click() for the Button, when you pick NextBackButton > myButtonClick you’ll see it request an int value. Set this to 1 for your forwards button and to -1 for your back button and use it to adjust a counter.
Use the counter in myButtonClick to keep track of thing and test the count so that it doesn’t go below 0 or greater than 3.
What some terrible code… Here is a complete rework I can suggest you. It involves more classes, but is way more extensible and manageable that what you have right now.
CODE NOT TESTED
NextBackButton.cs
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
public class NextBackButton: MonoBehaviour
{
[SerializeField] private Button previousButton;
[SerializeField] private Button nextButton;
[SerializeField] private Text previousButtonLabel;
[SerializeField] private Text nextButtonLabel;
private int currentOption = 0;
private ButtonListener[] listeners = new ButtonListener[]
{
new Foo(), new Bar(), new Baz("hello world")
};
private void Start()
{
SetListeners(0);
previousButton.onClick.AddListener(() => SetListeners(currentOption - 1));
nextButton.onClick.AddListener(() => SetListeners(currentOption + 1));
}
void SetListeners(int index)
{
listeners[currentOption].RemoveAsListener();
listeners[(currentOption - 1 + listeners.Length) % listeners.Length].RemoveAsListener();
currentOption = (index + listeners.Length) % listeners.Length;
previousButton.interactable = currentOption > 0;
if (previousButton.interactable)
{
listeners[(currentOption - 1 + listeners.Length) % listeners.Length].AddAsListener(previousButton);
listeners[( currentOption - 1 + listeners.Length ) % listeners.Length].SetLabel(previousButtonLabel);
}
else
{
previousButtonLabel.text = "";
}
nextButton.interactable = currentOption < listeners.Length - 1;
if (nextButton.interactable)
{
listeners[currentOption].AddAsListener(nextButton);
listeners[currentOption].SetLabel(nextButtonLabel);
}
else
{
nextButtonLabel.text = "";
}
}
}
ButtonListener.cs
public abstract class ButtonListener
{
protected Button button;
public abstract void SetLabel(Text text);
public virtual void AddAsListener(Button button)
{
this.button = button;
button.onClick.AddListener(PerformAction);
}
public virtual void RemoveAsListener()
{
if(button == null) return;
button.onClick.RemoveListener(PerformAction);
}
protected abstract void PerformAction();
}
Foo.cs = your RunCode0 function
public class Foo : ButtonListener
{
public override void SetLabel(Text text)
{
text.text = "Foo";
}
protected override void PerformAction()
{
Debug.Log("Hey, I'm foo!");
}
}
Bar.cs = your RunCode1 function
public class Bar : ButtonListener
{
private int selectedCount = 0;
public override void SetLabel(Text text)
{
text.text = "Bar";
}
public override void AddAsListener(Button button)
{
base.AddAsListener(button);
Debug.Log("Listener added"); // Just for the sake of the example, you don't need the function
}
protected override void PerformAction()
{
selectedCount++;
Debug.Log("This option has been clicked " + selectedCount + " times");
}
}
Baz.cs = your RunCode2 function
public class Baz : ButtonListener
{
private string input;
public Baz(string input)
{
this.input = input;
}
public override void SetLabel(Text text)
{
text.text = input;
}
protected override void PerformAction()
{
Debug.Log(input);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class NextBackButton: MonoBehaviour
{
[Range(0, 3)] public int currentOption = 0;
[SerializeField] private Button previousButton;
[SerializeField] private Button nextButton;
private void Start()
{
// set the initial text of the button
//setButtonText(currentOption);
// add an event listener to look out for button clicks
previousButton.onClick.AddListener(() => myButtonClick(currentOption--));
nextButton.onClick.AddListener(() => myButtonClick(currentOption++));
}
private void Update()
{
// Minimum Value
if (currentOption < 0)
{
currentOption = 0;
}
// Maximum Value
if (currentOption > 3)
{
currentOption = 3;
}
}
public void myButtonClick(int optionValue)
{
switch (currentOption)
{
case 0:
// run stuff for option 1
RunCode0();
// change the text on the button to be the next option
optionValue++;
//setButtonText(currentOption);
break;
case 1:
Debug.Log("Doing option 2 things");
RunCode1();
// change the text on the button to be the next option
optionValue++;
//setButtonText(currentOption);
break;
case 2:
Debug.Log("Doing option 3 things");
RunCode2();
// change the text on the button to be the next option
optionValue++;
//setButtonText(currentOption);
break;
case 3:
Debug.Log("Doing option 4 things");
RunCode3();
// change the text on the button to be the next option
optionValue++;
//setButtonText(currentOption);
break;
}
}
void setButtonText(string buttonText)
{
previousButton.transform.GetChild(0).GetComponent<Text>().text = buttonText;
nextButton.transform.GetChild(0).GetComponent<Text>().text = buttonText;
}
public void RunCode0()
{
//Do something
}
public void RunCode1()
{
//Do something
}
public void RunCode2()
{
//Do something
}
public void RunCode3()
{
//Do something
}
}