Search Unity

  1. Unity 2020.1 has been released.
    Dismiss Notice
  2. We are looking for feedback on the experimental Unity Safe Mode which is aiming to help you resolve compilation errors faster during project startup.
    Dismiss Notice
  3. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Help Wanted Adding script to gameobject is not done properly?

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

  1. dredknight


    Sep 6, 2018
    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;
    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.         {
    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


    Feb 22, 2014
    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


    Sep 6, 2018
    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


    Feb 22, 2014
    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.