Search Unity

Question Index was outside of bound on Button.Invoke()

Discussion in 'UI Toolkit' started by rangolee302, Jun 10, 2021.

  1. rangolee302

    rangolee302

    Joined:
    Feb 1, 2018
    Posts:
    22
    Code (CSharp):
    1.  
    2.     void OnEnable()
    3.     {
    4.         UIDocument document = GetComponent<UIDocument>();
    5.         VisualElement root = document.rootVisualElement;
    6.  
    7.         testa = root.Q<Button>("testa");
    8.         testb = root.Q<Button>("testb");
    9.         testa.clicked += Something;
    10.         testa.clicked += OtherThing;
    11.         Action temp = null;
    12.         temp += Something;
    13.         temp += OtherThing;
    14.         testb.clicked += () =>
    15.         {
    16.             testa.clicked -= temp;
    17.         };
    18.     }
    19.  
    20.     void Something()
    21.     {
    22.         Debug.Log("test");
    23.     }
    24.  
    25.     void OtherThing()
    26.     {
    27.         Debug.Log("other");
    28.     }
    29.  
    After clicking testb button to unsubscribe the functions, click testa will result "Index was outside the bounds of the array." Error

    I know I can do
    testa.clicked -= OtherThing;
    testa.clicked -= Something;

    But the code should work too in C#. At least I tried on a non-Unity environment
    I just want to know why this happen.
     
  2. cpalma-unity

    cpalma-unity

    Unity Technologies

    Joined:
    Nov 30, 2020
    Posts:
    110
    Hi. I was able to reproduce the same issue in a non-Unity environment, so it's more of a C# issue.

    Code (CSharp):
    1. using System;
    2.  
    3. namespace ConsoleApplication1
    4. {
    5.     internal class Program
    6.     {
    7.         public static void Main(string[] args)
    8.         {
    9.             Console.WriteLine("Program started");
    10.             Action temp = null;
    11.             temp += Something;
    12.             temp += OtherThing;
    13.  
    14.             Action action = null;
    15.             action += Something;
    16.             action += OtherThing;
    17.             action -= temp;
    18.             action?.Invoke();
    19.            
    20.             Console.WriteLine("Program ended");
    21.         }
    22.        
    23.         static void Something()
    24.         {
    25.             Console.WriteLine("test");
    26.         }
    27.         static void OtherThing()
    28.         {
    29.             Console.WriteLine("other");
    30.         }
    31.     }
    32. }
    This would also cause the
    IndexOutOfRangeException
    . I'm not sure why this is happening, I noticed the action becomes null when you unsubscribe the methods one by one but it doesn't become null when you remove them at once using
    temp
    , causing the exception when invoke is called. As a good practice, you should always unsubscribe the same function you are subscribing to the action.

    I hope this helps a bit :)
     
    rangolee302 likes this.
  3. rangolee302

    rangolee302

    Joined:
    Feb 1, 2018
    Posts:
    22
    which version of .Net you are using?
    I am running at .Net 5
    upload_2021-6-11_16-18-55.png
     
  4. cpalma-unity

    cpalma-unity

    Unity Technologies

    Joined:
    Nov 30, 2020
    Posts:
    110
    It is a .net version issue. It fails on .net 4.8 but it works fine on .net 5 :)
     
    rangolee302 likes this.