Search Unity

Question Adding script to gameobject is not done properly?

Discussion in 'Scripting' started by dredknight, Jun 28, 2020.

  1. dredknight

    dredknight

    Joined:
    Sep 6, 2018
    Posts:
    37
    Dear community,

    I am battling some weird issue I cannot get why it is happening :(.

    The current project has a prefab with the following components - Rect Transform, Canvas Renderer, Image, Button, Event Trigger, Script called Click Action.

    The function that instantiates it and fills in scripts public variables works properly.

    i do decided to remove the prefab and create the GameObject through scripts. At runtime it can be seen that all components are added and populated except the Click Action script and I do not understand why.

    To be precise the component Click Action is assigned but variables inside it are not populated and the following error is given:
    NullReferenceException: Object reference not set to an instance of an object
    GameManager.CreateButton (System.Int32 size, UnityEngine.GameObject parent, UnityEngine.Vector2 pCoords, System.Collections.Generic.List`1[T] text, System.Func`2[T,TResult] function, System.Int32 buttons, System.String source, System.String name, System.Object[] args) (at Assets/Scripts/GameManager.cs:263)

    MainMenu.Start () (at Assets/Scripts/MainMenu.cs:27)
    .
    Here is the script code:
    Code (CSharp):
    1. public class ClickAction : MonoBehaviour, IPointerClickHandler
    2. {
    3.     public UnityEvent OnLeft, OnRight, OnMiddle;
    4.     public int buttons;
    5.  
    6.     public void OnPointerClick(PointerEventData eventData)
    7.     {
    8.         if (eventData.button == PointerEventData.InputButton.Left)
    9.             OnLeft.Invoke();
    10.         else if (eventData.button == PointerEventData.InputButton.Right & buttons > 1)
    11.             OnRight.Invoke();
    12.         else if (eventData.button == PointerEventData.InputButton.Middle & buttons > 2)
    13.             OnMiddle.Invoke();
    14.     }  
    15. }
    and here is the method that creates the object and attach the script with vars.
    Code (CSharp):
    1. if (function != null)
    2.         {
    3.            
    4.             List<object> listL = new List<object>();
    5.             List<object> listR = new List<object>();
    6.             List<object> listM = new List<object>();
    7.             listL.Add("left");
    8.             listR.Add("right");
    9.             listM.Add("middle");
    10.             if (args != null)
    11.             {
    12.                 listL.AddRange(args);
    13.                 listR.AddRange(args);
    14.                 listM.AddRange(args);
    15.             }
    16.             object[] ListL = listL.ToArray();
    17.             object[] ListR = listR.ToArray();
    18.             object[] ListM = listM.ToArray();
    19.             //ClickAction butAction = button.GetComponent<ClickAction>();
    20.             ClickAction butAction = button.AddComponent<ClickAction>();
    21.             butAction.buttons = buttons;                                                // this is not populated in the script
    22.             butAction.OnLeft.AddListener(() => function(ListL));           // this is not populated in the script
    23.             butAction.OnRight.AddListener(() => function(ListR));       // this is not populated in the script
    24.             butAction.OnMiddle.AddListener(() => function(ListM));     // this is not populated in the script
    25.         }
    The same code is used to fill in the prefab so it makes zero sense to not be working :(.

    Any advice is welcomed.
     

    Attached Files:

  2. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    Always point out the exact line where the error is occurring.

    With a null reference error, you somewhere have an expression "someVariable.something" where "someVariable" is null. If you can't immediately tell which variable just from the line number, then split that line into smaller pieces until you can tell exactly which variable (or step through in a debugger). Then trace that variable backwards until you find the point where it should have been given a non-null value (but wasn't) or was incorrectly assigned a null value.
     
  3. dredknight

    dredknight

    Joined:
    Sep 6, 2018
    Posts:
    37
    Thank you @Antistone. I could not solve the issue but that helped a lot to understand what is going on.

    It seems something very wrong happens with Unity and the code is randomly skipping commands and just doing a few randomly until it crashes (that is a few lines out of 2 different scripts which is even weirder).
    As soon as i switch to prefab instantiation all scripts start working perfectly.

    I will continue investigating further tomorrow.
     
  4. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    The odds that that is what is happening are approximately zero. Computers just don't pull random crap unless there is a hardware failure. When it looks like that's what they're doing, it means you haven't understood what's going on.

    Though a run-time error will cause the rest of the current magic-method to be skipped. If you do a bunch of separate things and some of them error, then you will get skips in the ones that errored and not in the ones that succeeded, which may result in certain lines of code sometimes executing and sometimes not. But any individual error always skips the rest of the current thing (or more precisely, it bubbles upward until caught by a try-catch, which will be in UnityEngine if you don't have one of your own).

    Even if this is a Unity bug (which I wouldn't conclude without a lot more investigation), it won't be randomly skipping lines.