0

good day I am trying to have two onclick events on one button. then execute one before the other I use the code below, but it executes at the same time.

  void Start() {
      someUIButtonReference.onClick.AddListener(SomeFunction1); // first
      someUIButtonReference.onClick.AddListener(SomeFunction2); // second
  }
  void SomeFunction1() {
      Debug.Log("SomeFunction1");
  }
  void SomeFunction2() {
      Debug.Log("SomeFunction2");
  }
derHugo
  • 83,094
  • 9
  • 75
  • 115
  • **Nothing** in c# executes "at the same time" .. the listeners are called in that order they where attached ... one after the other ... Do you rather mean you want to alternate between the two callbacks and on each click only execute one of them? – derHugo Jan 13 '22 at 19:54
  • @derHugo hi I want to alternate between the two functions in one click. is there a way to do that? –  Jan 14 '22 at 05:23
  • @derHugo _"**Nothing in c#** executes "at the same time""_ - two threads on different cores would disagree with you –  Jan 14 '22 at 07:50
  • @MickyD even using different threads hitting exactly the timing for to calls happening at exactly the se time is pretty unlikely ;) I think we all know what I ment by that (therefore there are the `"` you most probably noted ;) ) and there is obviously no multithreading involved here ... – derHugo Jan 14 '22 at 09:34

2 Answers2

1

It sounds to me what you actually want is alternate between the callbacks and each click only execute one of them.

If you have only two of them you could simply use a bool flag and do

private bool isSecondClick;

void Start() 
{
    // Use a wrapper callback instead
  someUIButtonReference.onClick.AddListener(HandleClick);
}

private void HandleClick()
{
    if(!isSecondClick)
    {
        SomeFunction1();
    }
    else
    {
        SomeFunction2();
    }

    isSecondClick = !isSecondClick;
}

void SomeFunction1()
{
    Debug.Log("SomeFunction1");
}

void SomeFunction2() 
{
    Debug.Log("SomeFunction2");
}

If there are going to be more callbacks then you could rather use something like e.g.

private int index;

private Action[] listeners = new Action[]
{
    SomeFunction1,
    SomeFunction2,
    SomeFunction3,
    ...
};

void Start() 
{
    // Use a wrapper callback instead
  someUIButtonReference.onClick.AddListener(HandleClick);
}

private void HandleClick()
{
    var action = listeners[index];

    action.Invoke();

    index = (index + 1) % listeners.Length;
}

void SomeFunction1()
{
    Debug.Log("SomeFunction1");
}

void SomeFunction2() 
{
    Debug.Log("SomeFunction2");
}

void SomeFunction3() 
{
    Debug.Log("SomeFunction3");
}

...
derHugo
  • 83,094
  • 9
  • 75
  • 115
0

You could define a flag and use it in a lambda expression to alternate between the functions. The flag will be closured.

bool flag = false;
someUIButtonReference.onClick.AddListener
(
    () => flag = !flag ? SomeFunction1() : SomeFunction2()
);
John Wu
  • 50,556
  • 8
  • 44
  • 80
  • Just a sidenote regarding lambda: Have in mind that a listener registered as a lambda can not be removed afterwards. Not that it is the case for OP necessarily but something to keep in mind in general – derHugo Jan 14 '22 at 09:59