Search Unity

How to permanently change variable via Button OnClick Listener - C#

Discussion in 'Scripting' started by Assets3D, Nov 8, 2017.

  1. Assets3D

    Assets3D

    Joined:
    Feb 23, 2014
    Posts:
    5
    Hi Guys,

    I have a problem with dynamically created buttons. When I send variable trough AddListener it dose'nt change variable even If I use ref.

    simple example:

    void Start ()
    {
    createButton(variableIWantToChange);
    }

    void createButton(int variableGlobal)
    {
    GameObject goButton = (GameObject)Instantiate (prefabButton);
    goButton.transform.SetParent (ParentPanel, false);
    goButton.transform.localScale = new Vector3 (1, 1, 1);
    Button tempButton = goButton.GetComponent<Button> ();
    tempButton.GetComponentInChildren<Text> ().text = btnText;


    tempButton.onClick.AddListener (() => ButtonClicked ( variableGlobal));
    }
    void ButtonClicked (int variableRef)
    {
    variableRef ++; // it will not change variableGlobal
    }

    Same with Ref:

    void createButton(ref int variableGlobal)
    {
    GameObject goButton = (GameObject)Instantiate (prefabButton);
    goButton.transform.SetParent (ParentPanel, false);
    goButton.transform.localScale = new Vector3 (1, 1, 1);
    Button tempButton = goButton.GetComponent<Button> ();
    tempButton.GetComponentInChildren<Text> ().text = btnText;


    int variableGlobal_2 = variableGlobal;
    tempButton.onClick.AddListener (() => ButtonClicked ( variableGlobal_2));
    }
    void ButtonClicked (int variableRef)
    {
    variableRef ++; // it will not change variableGlobal
    }

    Any idea ? How to change global variable trough dynamically created buttons OnClick. I will appreciate any help with this.

    Cheers,
    Dominik
     
  2. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    In order to make it compile, you had to copy the by-reference variable into a by-value variable. That by-value variable is then passed...um...by value...into ButtonClicked.

    Make it so that createButton takes an Action<int>, then define a method on the class that hosts the variable you want to change and pass that method in to createButton.
     
  3. Assets3D

    Assets3D

    Joined:
    Feb 23, 2014
    Posts:
    5
    ON CreateButton I want to pass different variables into the same ButtonClick listener method. The question is:
    How to change global variable trough dynamically created buttons OnClick where I pass different variables for each button. I will appreciate any help :)
     
  4. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Just follow @MaxGuernseyIII's advice. Though I think an Action<int> is not needed, but either an UnityEngine.Events.UnityAction or System.Action. Using the latter you'd create an UnityAction internally anyway.

    You'll then pass a lamda or any other matching method as either of both delegate types to the CreateButton method:

    Code (csharp):
    1. CreateButton(() => ++someVariable);
    2. // or
    3. CreateButton(() => someOtherVariable *= 2);
    You could also use an integer-wrapping reference type to achieve your goal with your approach, but that's pretty much up to you.
     
  5. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    It depends on where the value is coming from. If it is coming from the event, it needs to be an Action<int>. If it is intrinsic to the observer, then Action will suffice.