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:
- Followed the code for OnClick events listed on the MRTK documents https://microsoft.github.io/MixedRealityToolkit-Unity/Documentation/README_Interactable.html
public static void AddOnClick(Interactable interactable)
{
interactable.OnClick.AddListener(() => Debug.Log("Interactable clicked"));
}
Looked into GitHub thread https://github.com/microsoft/MixedRealityToolkit-Unity/issues/4456
Looked into the GitHub thread https://github.com/microsoft/MixedRealityToolkit-Unity/issues/5013
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.
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 ofi
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: