2

I have a struct array of toggles defined. I am adding a listener to each of them. Now I would like to know which toggle was changed when user presses on a toggle to change the value. How do I know from my script which toggle was changed and use it as an index?

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class ToggleData : MonoBehaviour {

    [System.Serializable]
    public struct toggleInfo {
        public Toggle toggle;
        public TextMeshProUGUI toggleText;
    }

    public toggleInfo[] toggles;

    public int toggleIndex = 0;

    // Start is called before the first frame update
    void Start () {

        for (int i = 0; i < toggles.Length; i++) {
            toggles[i].toggle.onValueChanged.AddListener (delegate {
                ToggleValueChanged (toggles[i].toggle);
            });
        }

    }

    void ToggleValueChanged (Toggle change) {
        Debug.Log ("toggle changed " + toggleIndex); //Get the index here
    }
}
Max
  • 141
  • 1
  • 9
  • 2
    `ToggleValueChanged (toggles[i].toggle, i);` and `void ToggleValueChanged (Toggle change, int index)` ? – derHugo Sep 17 '21 at 14:38
  • @derHugo I did try that but I am getting ```IndexOutOfRangeException: Index was outside the bounds of the array.``` error – Max Sep 17 '21 at 14:42
  • I am adding a total of 6 toggles from inspector window. – Max Sep 17 '21 at 14:45
  • Got it, I have to do like this ```int idx = i; toggles[idx].toggle.onValueChanged.AddListener (delegate { ToggleValueChanged (toggles[i].toggle, idx);});``` its because only one value can be assigned with an index. – Max Sep 17 '21 at 14:54

1 Answers1

2

You could e.g. use

for (int i = 0; i < toggles.Length; i++) 
{
    // Due to variable capturing in Linda expresions you have to store 
    // each value of i in a new variable
    // See https://learn.microsoft.com/dotnet/csharp/language-reference/operators/lambda-expressions#capture-of-outer-variables-and-variable-scope-in-lambda-expressions
    // and e.g. https://stackoverflow.com/questions/271440/captured-variable-in-a-loop-in-c-sharp
    var index = i;
    toggles[index].toggle.onValueChanged.AddListener (() => ToggleValueChanged (toggles[index].toggle, index));
}

And have

void ToggleValueChanged (Toggle change, int index) 
{
    Debug.Log ("toggle changed " + index);
}

Alternatively just don't use a struct but rather a class

public class toggleInfo { ... }

and use

for (int i = 0; i < toggles.Length; i++) 
{
    // Due to variable capturing in Linda expresions you have to store 
    // each value of i in a new variable
    // See https://learn.microsoft.com/dotnet/csharp/language-reference/operators/lambda-expressions#capture-of-outer-variables-and-variable-scope-in-lambda-expressions
    // and e.g. https://stackoverflow.com/questions/271440/captured-variable-in-a-loop-in-c-sharp
    var index = i;
    toggles[index].toggle.onValueChanged.AddListener (() => ToggleValueChanged (toggles[index]));
}

And have

void ToggleValueChanged (toggleInfo info) 
{
    Debug.Log ("toggle changed " + Array.IndexOf(toggles, info));
}
derHugo
  • 83,094
  • 9
  • 75
  • 115