Adding Complex Click Events HoloLens

280 views Asked by At

Summary:

  • Goal: create a dynamic table of contents on start
  • Expected results: if the user clicks button that corresponds to page x, the user will be directed to page x
  • Actual results: if the user clicked button that corresponds to page x, the user will be directed to the last page

What I have tried:

public static void AddOnClick(Interactable interactable)
{
    interactable.OnClick.AddListener(() => Debug.Log("Interactable clicked"));
}

Code: TOC = Table of Contents

private void TOCpage()
{
    GameObject TOC = new GameObject(); // holds table of contents buttons
    for(int i = 1; 1 <= pages.Count - 1; i++)
    {
        GameObject TOCgameObject = (GameObject)Instantiate(TOCButtonPrefab);
        var TOCButton = TOCgameObject.GetComponent<Interactable>();
        TOCbutton.OnClick.AddListener(() => TaskOnClick(i));
    }
}

public void TaskOnClick(int TOCButtonNumber)
{
    Debug.Log("Table of contents button number " + TOCButtonNumber + " clicked");
}

If user clicks on TOCbutton for page 1, and there are 7 pages, the user is directed to page 7.

1

There are 1 answers

0
Hernando - MSFT On

TOCbutton.OnClick.AddListener(() => TaskOnClick(i));

This happens because i is not local to the lambdas, but is defined in the outer scope, and it is accessed when the lambda is called — not when it is defined. At the end of the loop, the value of i is 7, so all the functions log 7.

Instead, you can create a local variable within the loop and assign it the value of the iteration variable or use foreach statement to do it under C#5.0 or later.

As a solution, you can refer to the following code:

        foreach (var i in Enumerable.Range(1, pages.Count))
        {
           GameObject TOCgameObject = (GameObject)Instantiate(TOCButtonPrefab);
           var TOCButton = TOCgameObject.GetComponent<Interactable>();
           TOCbutton.OnClick.AddListener(() => TaskOnClick(i));
        }