- Home /
Cannot change Button interactable in a UnityAction
Hello,
I have a UnityEngine.UI.Button
which, when clicked, increments a value and then makes itself disabled. This is what the code looks like:
Button button = CreateButton();
button.onClick.AddListener(() => {
Debug.Log("Hello World!");
button.interactable = false;
});
This prints "Hello World!" to the console when the button is clicked, but it does not disable itself. The following code works and disables the button before it is pressed:
Button button = CreateButton();
button.interactable = false;
button.onClick.AddListener(() => {
Debug.Log("Hello World!");
});
But this is not what I want. How can I get this to work?
UPDATE
It's not referencing the expected button. I have 20 separate canvases, each drawing their own set of buttons. Each canvas is on Screen Space - Camera, and they are all tied to their own cameras. I only have 1 camera active, though, but when I press the buttons, it references a button which is not a child of the canvas that I have visible. To explain this better, here is a screenshot of my hierarchy:
As you can see, I have several players, each with their own canvas and camera. The first player is the only one whose camera is active. But, for some reason, when I click the buttons drawn on the screen, they reference the buttons of other player's buttons. This is very strange... the canvases should only be rendering to their own player's cameras!
The buttons are never given a different value within my C#. The only time they ever are assigned a value is when they are initialized.
Also, another interesting little point, hovering over the buttons and clicking them does not change their color, but the EventSystem
still registers the button being clicked.
If you change this line
Debug.Log("Hello World!");
to this line:
Debug.Log("Hello World!", button);
does the correct/expected button get highlighted in the hierarchy when you click the "Hello World" in the console log?
Because if not, check if you assign button after you add the listener, button is a reference, so if you assign something else to it afterwards you could end up setting interactible of some other button.
That caused some strange results, see the update in the question.
Hmmm... Strange. Normally, this kind of error happens in a situation like this
Button button;
for (int i = 0; i < Length; i++)
{
button = CreateButton();
button.onClick.AddListener(() =>
{
button.interactable = false;
Debug.Log("Hello World!");
});
}
Where you constantly overwrite the button reference with a new value resulting in that when the onClick event gets called, button references the last button created in the for loop resulting in that it doesn't work. The fix there would be to place the Button button;
line inside the for loop so that you never assign a new value to an existing reference, but ins$$anonymous$$d declare new reference each time. $$anonymous$$ore info about that subject can be found in this great blogpost.
But sinse you claim that you don't assign anything to button I don't really know what the problem is. Unless you didn't understand me and are actuallly still doing something like what I described above.
Nope, that's defenitely not the problem. $$anonymous$$y button only has its value set when it's initialized. Thank you for your help, though.
Answer by meat5000 · Aug 18, 2016 at 05:14 PM
Did you add
using UnityEngine.EventSystems;
Just tried that, didn't change anything. Thanks for the answer, though.
Answer by Skyler_Hawkins · Aug 19, 2016 at 12:09 AM
I hope this can help out, try playing around with this to get it to fit what you need. I'm pretty new with buttons too, but I had this work for me. I'll write it out step-by-step for anyone that needs help understanding. You just have to make sure you add what you want the click to do in the "On Click ()" at the button of the Inspector.
using UnityEngine; using UnityEngine.UI; //have to have this when working with UI using System.Collections;
public class MenuButton : MonoBehaviour
{
public Canvas Menu;
public Button ButtonText;
// add more Public Button as you need i.e public Button Button2Text;
// this sets up your canvas and button(s)
void Start()
{
Menu = Menu.GetComponent<Canvas>();
ButtonText = ButtonText.GetComponent<Button>();
Menu.enabled = true;
ButtonText.enabled = true;
}
public void ButtonPress()
{
Debug.Log("Hello World!");
ButtonText.enabled = false;
}
// add more pulbic voids as need for each button that you need i.e public void Button2Press()
}
Add Script to your Canvas
Add your canvas to the Menu area of the Inspector of your Canvas
Add your Button(s) to the Button area of the Inspector of your Canvas
On your Button Inspector
Click the + button on the "On Click ()"
Add your Canvas to the Area that opens up
Click on drop down that says "No Function"
Go to the bottom and Click MenuButton
Find the Function you created in your script that you want (in this case "ButtonPress")
$$anonymous$$y code should do the exact same thing as what the editor does, this didn't change anything, but thanks for your answer!
Answer by DougMcFarlane · Aug 19, 2016 at 12:10 AM
Maybe your listener doesn't have a reference to the button?
Does this work?
Button button = CreateButton();
button.onClick.AddListener((button) => {
Debug.Log("Hello World!");
button.interactable = false;
});
If not, check that the listener is referencing the expected button, by changing your debug to:
Debug.Log("Button: " + button.name);
This gave some interesting results. I will edit the question to clarify and explain.