Search Unity

  1. Unity 2019.1 beta is now available.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. We're looking for insight from anyone who has experience with game testing to help us better Unity. Take our survey here. If chosen to participate you'll be entered into a sweepstake to win an Amazon gift card.
    Dismiss Notice
  4. On February 28th the Feedback website will shut down and be redirected to the Unity forums. See the full post for more information.
    Dismiss Notice
  5. Want to provide direct feedback to the Unity team? Join the Unity Advisory Panel.
    Dismiss Notice
  6. Unity 2018.3 is now released.
    Dismiss Notice
  7. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice

Passing int parameters to delegate function becomes reference passing

Discussion in 'Scripting' started by LucianoLin, Sep 15, 2018.

  1. LucianoLin

    LucianoLin

    Joined:
    Nov 29, 2017
    Posts:
    7
    I bind three delegate functions with parameter 0,1,2 to three buttons. Since int is value type, so i think the output should be 0,1,2. But it's not. The output is 3,3,3. It means they are referenced to the same i, which becomes 3 at last.

    Can somebody tells me why it happens?

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5.  
    6. public class TestScript : MonoBehaviour {
    7.  
    8.     public Button[] buttons;
    9.  
    10.     // Use this for initialization
    11.     void Start () {
    12.         for(int i=0; i < 3; i++){
    13.             int index = new int();
    14.             index = i;
    15.             buttons[i].onClick.AddListener(delegate { OnSelect(index); });
    16.         }
    17.     }
    18.    
    19.     // Update is called once per frame
    20.     void Update () {
    21.        
    22.     }
    23.  
    24.     private void OnSelect(int index=0){
    25.         Debug.Log(index);
    26.     }
    27. }
     
  2. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    1,849
    Anonymous delegates capture the entire context of their local function call. Try calling something like...
    Code (csharp):
    1.  
    2. void AddListener(Button button, int parameter)
    3. {
    4.    button.onClick.AddListener(delegate { OnSelect(parameter);  });
    5. }
    6.  
    ... in your loop as a workaround. That should create a different local context.

    Honestly, I would just move away from anonymous delegates entirely and create your logic in a different way. They're very tricky to control the lifetime and context of, and are hard to debug.
     
  3. LucianoLin

    LucianoLin

    Joined:
    Nov 29, 2017
    Posts:
    7
    You are right. Thanks for your help.

    Actually i do in this way because i have multiple buttons which should have similar onclick event, just with different parameters(like the one show before). Is there any better way to realize this functionalities?