Instantiation problems and unresponsive scripts

Hi, everyone!

I’m trying to create a Scene Placement Tool program where you can add objects to a scene from an XML database, but I’m having several problems. Attached is a screen to demonstrate some of the problems.

Here are three scripts where there should be most of the errors:

--- UIManager.cs ---

using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;

public class UIManager : MonoBehaviour
{
    private GameObject pausePanel;
    private bool isPaused;

    private GameObject selectionUI;
    private bool showSelectionUI;

    private GameObject confirmDeletionPanel;

    public SceneObject selectedSceneObject;

    // Category Filter variables
    private int panelID = 0;
    private GameObject[] categoryPanels;
    private GameObject emergencyCategoryPanel;
    private GameObject vehiclesCategoryPanel;
    private GameObject actorsCategoryPanel;
    private GameObject miscCategoryPanel;

    public bool ShowSelectionUI
    {
        get { return showSelectionUI; }
        set { showSelectionUI = value; }
    }

    private List<string> resolutionOptions = new List<string>()
            { "800x600", "1366x768", "1920x1200" };
    private Dropdown resolutionDropdown;
    private Text selectedResolution;

    [SerializeField]
    private bool windowedRadioButton;

    private void Start()
    {
        categoryPanels          = GameObject.FindGameObjectsWithTag("Category Panel");
        emergencyCategoryPanel  = GameObject.Find("Emergency Panel");
        vehiclesCategoryPanel   = GameObject.Find("Vehicles Panel");
        actorsCategoryPanel     = GameObject.Find("Actors Panel");
        miscCategoryPanel       = GameObject.Find("Misc Panel");
        SwitchToPanel(panelID);

        selectedSceneObject = FindObjectOfType<SceneObject>();

        confirmDeletionPanel.SetActive(false);
        isPaused = false;

        // default screen resolution size
        Camera.main.aspect = 1920f / 1200f;

        PopulateResolutionList();
    }

    private void Update()
    {
        selectionUI.SetActive(showSelectionUI); // THIS CAUSES A MULTIPLE EXCEPTION

        if (isPaused)
        { PauseSession(true); }
        else
        { PauseSession(false); }

        if (Input.GetButtonDown("Cancel"))
        { SwitchPause(); }
    }

    public void SwitchToPanel(int panelID)
    {
        foreach (GameObject panel in categoryPanels)
        { panel.gameObject.SetActive(false); }

        switch (panelID)
        {
            case 0:
                emergencyCategoryPanel.gameObject.SetActive(true);
                break;
            case 1:
                vehiclesCategoryPanel.gameObject.SetActive(true);
                break;
            case 2:
                actorsCategoryPanel.gameObject.SetActive(true);
                break;
            case 3:
                miscCategoryPanel.gameObject.SetActive(true);
                break;
        }
    }

    private void PauseSession(bool pauseState)
    {
        if (pauseState)
        {
            pausePanel.SetActive(true);
            Time.timeScale = 0.0f; // stop time execution
        }
        else
        {
            Time.timeScale = 1.0f; // normal time execution
            pausePanel.SetActive(false);
        }
    }

    public void SwitchPause()
    {
        if (isPaused)
        { isPaused = false; }
        else
        { isPaused = true; }
    }

    public void ExitProgram()
    {
        Application.Quit();
    }

    public void PopulateResolutionList()
    {
        resolutionDropdown.AddOptions(resolutionOptions);
    }

    public void ResolutionDropdown_IndexChanged(int resIndex)
    {
        selectedResolution.text = resolutionOptions[resIndex];

        if (resIndex == 0)
        {
            Screen.SetResolution(800, 600, true);
        }
        else if (resIndex == 1)
        {
            Screen.SetResolution(1366, 768, true);
        }
        else if (resIndex == 2)
        {
            Screen.SetResolution(1920, 1200, true);
        }
    }

    public void WindowedMode()
    {
        if (windowedRadioButton)
        {
            Screen.fullScreen = !Screen.fullScreen;
        }
    }

    public void ShowConfirmDeletionPanel()
    {
        confirmDeletionPanel.SetActive(true);
    }

    public void DeleteObject()
    {
        Destroy(selectedSceneObject); // TODO fix (it destroys the script!)
        confirmDeletionPanel.SetActive(false);        
    }
}



--- ObjectManager.cs ---

using UnityEngine;
using System.Collections.Generic;
using System.Xml; // TODO create object catalogue database

public class ObjectManager : MonoBehaviour
{
    [SerializeField]
    private GameObject cursor;
    public GameObject newSceneObject = null;

    public List<GameObject> sceneObjectsCollection;
    public int objectsInScene = 0;
    
    private void Start ()
    {
        newSceneObject = GameObject.FindGameObjectWithTag("Selectable") as GameObject;

        XmlDocument objectData = new XmlDocument();
        //objectData.Load("sceneobjects.xml"); // TODO make path
        XmlNodeList nodeList = objectData.SelectNodes("sceneobjects"); // get all <sceneobject> nodes

        foreach (XmlNode node in nodeList) // for each <sceneobject> node
        {
            // TODO code here
        }

        // make a list of all objects
        sceneObjectsCollection = new List<GameObject>();

        for (int index = 0; index < sceneObjectsCollection.Count; index++)
        {
            sceneObjectsCollection.Add(Instantiate(gameObject));
        }
    }
    
    public void CreateSceneObject()
    {
        GameObject instantiatedObject = Instantiate(Resources.Load("Prefabs/Cube")) as GameObject;
        
        instantiatedObject.transform.position = cursor.transform.position;
        instantiatedObject.transform.rotation = cursor.transform.rotation;
        instantiatedObject.tag = "Selectable";

        // access variable from SceneObject class (it's static in SceneObject)
        instantiatedObject = SceneObject.selectedSceneObject;
        instantiatedObject = gameObject.AddComponent<SceneObject>().GetComponent<GameObject>();

        objectsInScene++;
    }
}

And finally, this is what should allow selection, which should highlight the object and show/hide the three buttons.

--- SceneObject.cs ---

using UnityEngine;

public class SceneObject : MonoBehaviour
{
    // TODO can it be private?
    public static GameObject selectedSceneObject = null;
    private GameObject unselectedSceneObject;

    private ObjectManager objectManagerScript;

    private float selectMultiplyRed = 4f;
    private float selectMultiplyGreen = 4f;
    private float selectMultiplyBlue = 4f;
    private Color unselectedColor;
    
    private static Transform selectTransform = null;
    private bool isSelected = false;

    /// object drag variables 
    private Vector3 screenPoint;
    private Vector3 offset;
    private float mouseRotateSpeed = 15f;

    private void Start()
    {
        ObjectManager objectManager = GetComponent<ObjectManager>();

        // access instantiated GameObject through Object Manager
        objectManagerScript = GameObject.FindGameObjectWithTag("Selectable").GetComponent<ObjectManager>();

        selectedSceneObject = GetComponent<GameObject>();
        if (selectedSceneObject == null)
        {
            Debug.Log("No object");
            this.GetComponent<Renderer>();
            //selectedSceneObject.AddComponent<Renderer>();
        }

    }
    
    public void OnMouseDown()
    {
        SelectionHighlight();
        if (isSelected && transform != selectTransform)
        { isSelected = false; }

        if (Input.GetMouseButton(0))
        {
            RaycastHit hitInfo = new RaycastHit();
            bool hit = Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hitInfo);

            if (hit)
            {
                // access UIManager class using a string from the hierarchy
                GameObject.Find("UIManager").GetComponent<UIManager>().ShowSelectionUI = true;

                SelectionHighlight();
            }
        }
        else
        {
            GameObject.Find("UIManager").GetComponent<UIManager>().ShowSelectionUI = false;

            isSelected = false;
        }

        RemoveHighlight();
    }

    private void OnMouseEnter()
    {
        SelectionHighlight();
    }

    private void OnMouseExit()
    {
        RemoveHighlight();
    }

    void OnMouseDrag()
    {
        gameObject.GetComponent<Renderer>().material.color = new Color(1f, 1f, 1f, 0.5f);

        if (Input.GetMouseButton(0))
        {
            Vector3 mouseScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z);
            Vector3 mousePointerPosition = Camera.main.ScreenToWorldPoint(mouseScreenPoint) + offset;
            transform.position = mousePointerPosition;
        }        
        
        // rotation functionality
        if (Input.GetMouseButton(2))
        {
            transform.rotation = Quaternion.AngleAxis(-Input.GetAxis("Mouse X") * mouseRotateSpeed, transform.up) * transform.rotation;
        }
    }

    private void SelectionHighlight()
    {
        float red = unselectedColor.r * selectMultiplyRed;
        float green = unselectedColor.g * selectMultiplyGreen;
        float blue = unselectedColor.b * selectMultiplyBlue;

        gameObject.GetComponent<Renderer>().material.color = new Color(red, green, blue);

        // TODO add cube programmatically
        //GameObject.AddComponent<T>("Cube");

        // drag functionality
        screenPoint = Camera.main.WorldToScreenPoint(gameObject.transform.position);
        offset = gameObject.transform.position - Camera.main.ScreenToWorldPoint
            (new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));
    }

    private void RemoveHighlight()
    {
        gameObject.GetComponent<Renderer>().material.color = unselectedColor;
        unselectedSceneObject.GetComponent<Renderer>().material.color = unselectedColor;
    }

    public void RotateClockwise()
    {
        selectedSceneObject.transform.Rotate(0, 45, 0);
    }

    public void RotateCounterClockwise()
    {
        selectedSceneObject.transform.Rotate(0, -45, 0);
    }
}

Sorry for the long post. Hope it makes sense.

Thank you!

confirmDeletionPanel is not being set… that’s the first of your errors.

try to format only the code - that way the error messages are consistent with the code (i.e. line numbers match up… the first error is on line 52 as posted)

Thanks, I added private access and added the following objects in the inspector:

[SerializeField]
private GameObject pausePanel;
...
[SerializeField]
private GameObject confirmDeletionPanel; 
...
[SerializeField]
private Dropdown resolutionDropdown;

I also added private ProgramManager programManager;in SceneObject.cs, as well as programManager.selectedSceneObject = this.gameObject; in its OnMouseDown() method.

This is ProgramManager.cs script:

using UnityEngine;
using UnityEngine.UI;
using System.IO; // TODO implement save/load functionality

public class ProgramManager : MonoBehaviour
{
    public GameObject settingsButton;
    public GameObject mainMenu;

    private Image menuPanel;
    private Image backButton;

    public GameObject selectedSceneObject { get; set; } // NEW LINE

    private bool showMenu = false;

    private void Start()
    {
        settingsButton = FindObjectOfType<GameObject>();
        mainMenu = FindObjectOfType<GameObject>();

        menuPanel = GetComponent<Image>();
        backButton = GetComponent<Image>();

        menuPanel.enabled = false;
        backButton.enabled = false;
    }

    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            showMenu = true;
        }
    }


    public void DeleteObject()
    {
        Destroy(selectedSceneObject); // TODO fix (it destroys the script!)
    }
}

I get these errors whenever I instantiate the cube

MissingComponentException: There is no 'GameObject' attached to the "Cube(Clone)" game object, but a script is trying to access it.
You probably need to add a GameObject to the game object "Cube(Clone)". Or your script needs to check if the component is attached before using it.

MissingComponentException: There is no 'GameObject' attached to the "ObjectManager" game object, but a script is trying to access it.
You probably need to add a GameObject to the game object "Object Manager". Or your script needs to check if the component is attached before using it.

The component in Object Manager is intentionally left blank because that should be the selection that dynamically changes (added to the inspector) each time an object is selected, but I don’t know how to do that.