Attributes of component are being set to null.

Hi, I’m having a problem where the attributes of a script attached to a GameObject are being set to null.

Below is the code that creates this GameObject, it is triggered by a mouse click.

private void addProcessor(Vector3 position)
    {
        if (selectionManager.GetInventory(selectionManager.GetSelectionInt()) > 0)
        {
            EventManager.Instance.TriggerResetProcessors();

            GameObject selection = selectionManager.GetSelection();
            Vector3 rotation = selectionManager.GetRotation();
            Vector3 gridPos = grid.GetNearestGridPos(position);

            GameObject p = Instantiate(selection, gridPos + new Vector3(0, 0.5f, 0), Quaternion.Euler(rotation));
            Debug.Log("Adding processor: " + p.name);
            p.GetComponentInChildren<AbstractProcessor>().enabled = true;
            p.transform.parent = this.transform;

            grid.SetCellValue(position, p);
            selectionManager.UpdateInventory(selectionManager.GetSelectionInt(), -1);

            EventManager.Instance.TriggerFireEmitters();
        }
    }

The GameObject initially functions as intended, but immediately after it has fulfilled it’s function all of the attributes on the script I attached to it are set to null.

The only thing that seems to consistently solve the problem is commenting out the drawPreview() function shown below.

    void Update()
    {
        DestroyImmediate(preview, true);
        tooltipManager.ClearProcessorTooltips();
        Ray ray = Camera.main.ScreenPointToRay(Mouse.current.position.ReadValue());
        if ((Physics.Raycast(ray, out RaycastHit hitData)) &&
            (grid.GetXY(hitData.point, out int x, out int y)))
        {
            GameObject value = grid.GetCellValue(hitData.point);

            if (value == null)
            {
                Debug.Log("Drawing preview.");
                preview = drawPreview(hitData.point);
            }
            else
            {
                tooltipManager.CreateProcessorTooltip(value.GetComponentInChildren<AbstractProcessor>());
            }
        }
    }

    private GameObject drawPreview(Vector3 location)
    {
        GameObject selection = selectionManager.GetSelection();
        Vector3 rotation = selectionManager.GetRotation();
        Vector3 gridPos = grid.GetNearestGridPos(location);
        GameObject newPreview = Instantiate(selection, gridPos + new Vector3(0, 0.5f, 0), Quaternion.Euler(rotation));
        StandardShaderUtils.makeTransparent(newPreview);
        newPreview.transform.parent = this.transform;
        return newPreview;
    }

What’s confusing though, is that the “Drawing preview.” message doesn’t get logged in between the point where my GameObject is functioning correctly and the point where all those values are null. So if the drawPreview function doesn’t get run then why does commenting it out solve the problem? And What exactly is causing my GameObject’s values to get set to null?

One thing to note is that if the drawPreview function were to be called at that point in time it would be trying to create an instance of the same prefab the original object uses, at the same location. My original thought was that maybe this object is overwriting the old one somehow, but then if the function isn’t being run then I’m not sure that theory checks out.

Possibly because you are using DestroyImmediate. Is Preview getting set anywhere else in your code? if it get set to “this” that would explain your nulls

Generally that function should only be used in Editor scripts, or in the rare case you really need something destroyed before the end of frame. What’s especially worrying is that you’ve set the 2nd parameter to true which lets it permanently destroy project assets. DestroyImmeadiate immeaditely nulls all the references on the targeted object, Destroy does so at the end of the frame.

Try commenting out the destroyimmeadiate. Instantiate the preveiw once (like in AddProcessor) and just activate/Deactivate in Update instead.

1 Like

Thanks for your help, replacing the DestroyImmediate with a normal destroy helped right away, another thing that helped for anyone with a similar problem was making sure that I destroy/deactivate the preview before addProcessor instantiated the second object. The DestroyImmediate must have been nulling all the references on both objects like you said.