# Problem picking up a value, Delegate

I'm having trouble passing values that are inside an int function to an onclick delegate.

this script causes the object to move in vector3 (-1 to the left and 1 to the right), these two values are inside the (int value), but I am trying to pass them to a delegate, but when inserting it it is adding different values than being in the script

video of the problem

private int index, index2 = 0;
[SerializeField]
private Vector3[] Myposic1, Myposic2;
[SerializeField]
private Button left, right;//here I change the positions of Myposic1, Myposic2
[SerializeField]
private float time;
public int slide = 0;//index between Myposic1, Myposic2.

void Update() {
call();
}

public void previous()
{
slide--;
call();
}

public void next()
{
slide++;
call();
}

void call()
{
if (slide <= 0)
{
slide = 0;
}

if (slide >= 1)
{
slide = 1;
}

if (slide == 0)
{
this.transform.position = Vector3.Lerp (this.transform.position, Myposic1[index], Time.deltaTime*time);
if (index == Myposic1.Length - 1)
right.interactable = false;
else
right.interactable = true;

if (index == 0)
left.interactable = false;
else
left.interactable = true;
Debug.Log("1");
}

if (slide == 1)
{
this.transform.position = Vector3.Lerp (this.transform.position, Myposic2 [index2], Time.deltaTime*time);
if (index2 == Myposic2.Length - 1)
right.interactable = false;
else
right.interactable = true;

if (index2 == 0)
left.interactable = false;
else
left.interactable = true;
Debug.Log("2");
}
}

public void player(int valor) {
index = index + valor;
}

public void player2(int valor2) {
index2 = index2 + valor2;
}


I'm not sure if I got the exact problem you were facing, but I will point out a few suggestions. Hopefully, one of them solves the issue.

1. In the call method, you have clamped the value of slide between 0 and 1. And then you have the two if conditions checking if the value is equals to 0 or 1. So it is bound to go into either one of the two if clauses.

Here, you are doing left.onClick.AddListener or right.onClick.AddListener, which is not a good idea, since you are calling the method call in Update. If you have to do this, then you might want to remove the listener you have already added

1. Myposic1 and Myposic2 are arrays, which I do not see initialized. You are trying to use it here, however this.transform.position = Vector3.Lerp (this.transform.position, Myposic2 [index2], Time.deltaTime*time);

I think this is the reason for the IndexOutOfRangeException being thrown.

1. I will talk about player2 and index2 for explaining, but I think the same will apply for player and index.

Consider this snippet of code that you've written:

 right.onClick.AddListener(delegate { player2(1); }); this.transform.position = Vector3.Lerp (this.transform.position, Myposic2 [index2], Time.deltaTime*time); if (index2 == Myposic2.Length - 1) right.interactable = false;

So what will happen here is that, player2 will get called on the onClick event of the button. But the code that you have written after the delegate, will run on the same frame (on every frame in this case, as it is called in Update)

So when you are checking if (index2 == Myposic2.Length - 1), it will always pick the current value. If you want to get the updated values when doing this check, you would want to move the following code into the delegate as well.

• the problem was in (update), thanks for the tip. – Rangel May 26 at 5:06

You are adding a listener during the Update function. That means every update-tick, another listener gets added, but the already existing listners don't get removed. When you then finally click on the button, there are already a couple hundred listeners registered on those buttons. All the listener get executed and each one increments the value by one. So you get an increase of several hundred instead of just one as you would expect.

If you only want to register your listeners once, do so in the Start method. If you want to change the functionality of a button by registering a different listener, you need to remove the previous listener. You can do that with .onClick.RemoveListener(method) if you want to remove a specific listener (in that case you will have to keep a reference to your delegate around so you can remove it later) or .onClick.RemoveAllListeners() to get rid of any listeners on that button.

However, I would recommend you to avoid adding listeners with code if possible and instead add listeners via the inspector of the Button component. This is far less error-prone because you have a much better visualization of what a button does if you select it in the inspector. If you need the button to do something different depending on the current state of the game, then consider to make the decision about what to do in the button handler method itself.

• actually the way you said would work, but the purpose of using this logic was to make my menu clean and avoid creating multiple buttons, since "2 pairs of buttons" could do that. but it looks like I'll have to let it be – Rangel May 26 at 0:14
• but not giving up – Rangel May 26 at 5:06
• @Rangel You can do this with two buttons and fixed listener functions if the listener functions themselves decide what to do depending on the current state of the game. – Philipp May 26 at 9:11