Search Unity

  1. We are migrating the Unity Forums to Unity Discussions by the end of July. Read our announcement for more information and let us know if you have any questions.
    Dismiss Notice
  2. Dismiss Notice

Scriptable Object not being assigned to, which stops me from calling on its variables.

Discussion in 'Scripting' started by DaPizzaKing, Jun 6, 2022.

  1. DaPizzaKing

    DaPizzaKing

    Joined:
    Jan 14, 2016
    Posts:
    9
    So I have two scripts. One called Selectable Object which stores all the information for a specific object like its name, description, resource type, and some images. Here is that code:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5.  
    6. [CreateAssetMenu(fileName = "New Object", menuName = "Selectable")]
    7. public class SelectableObject : ScriptableObject
    8. {
    9.     public Image resourceImage;
    10.     public string resourceType;
    11.     public Image preview;
    12.     public string itemName;
    13.     public string description;
    14.     public GameObject selectable;
    15.     public int costToBuild;
    16. }
    17.  
    Now I'm trying to access these variables so I can assign them to text fields and images on a canvas. I am able to call on it just fine I believe but I get stuck when trying to assign a text field to the description variable declared in the scriptable object. Here is the code:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5. using TMPro;
    6.  
    7. public class BuildMenu : MonoBehaviour
    8. {
    9.     public Canvas canvas;
    10.     public GameObject objectPanel, preview, description, cost, resource, itemName;
    11.     public List<ScriptableObject> basics;
    12.     private SelectableObject selectableObject;
    13.     // Start is called before the first frame update
    14.     void Start()
    15.     {
    16.         canvas = GetComponent<Canvas>();
    17.         objectPanel = canvas.transform.Find("ObjectPanel").gameObject;
    18.         BasicsPanel();
    19.     }
    20.  
    21.     // Update is called once per frame
    22.     void Update()
    23.     {
    24.     }
    25.  
    26.     public void BasicsPanel()
    27.     {
    28.         int x = 0;
    29.         foreach (ScriptableObject scriptable in basics)
    30.         {
    31.             GameObject panel = Instantiate(objectPanel, canvas.transform);
    32.             selectableObject = Resources.Load<SelectableObject>(basics[x].name);
    33.             Debug.Log(basics[x].name);
    34.             preview = objectPanel.transform.Find("ObjectPreview").gameObject;
    35.             description = objectPanel.transform.Find("Description").gameObject;
    36.             cost = objectPanel.transform.Find("TileCost").gameObject;
    37.             resource = objectPanel.transform.Find("ResourceRequirement").gameObject;
    38.             itemName = objectPanel.transform.Find("ItemName").gameObject;
    39.             Vector3 pos = panel.transform.position;
    40.             panel.SetActive(true);
    41.             if(x >= 1)
    42.             {
    43.                 pos.x = (panel.transform.position.x + 310);
    44.                 Debug.Log(panel.transform.position + " : " + pos);
    45.             }
    46.             panel.transform.position = pos;
    47.             TextMeshPro tmpDescription = description.GetComponent<TextMeshPro>();
    48.             tmpDescription.text = selectableObject.description;
    49.             x++;
    50.         }
    51.     }
    52. }
    53.  
    The problem comes in at line 48 where I am assigning the text to "selectableObject.description". It throws a NullReference error. I'm not sure what the problem is, can anyone help me solve this?

    UPDATE**
    So I figured out how to load it correctly by using the resources folder. But I am still having issues assigning the text to the description even though the description ISNT null.
    Here is the new code:
    Code (CSharp):
    1.  
    2. foreach (ScriptableObject scriptable in basics)
    3.         {
    4.             GameObject panel = Instantiate(objectPanel, canvas.transform);
    5.             selectableObject = Resources.Load<SelectableObject>("ScriptableObjects/" + basics[x].name);
    6.             Debug.Log(selectableObject.name + " : " + selectableObject.description);
    7.             preview = objectPanel.transform.Find("ObjectPreview").gameObject;
    8.             description = objectPanel.transform.Find("Description").gameObject;
    9.             cost = objectPanel.transform.Find("TileCost").gameObject;
    10.             resource = objectPanel.transform.Find("ResourceRequirement").gameObject;
    11.             itemName = objectPanel.transform.Find("ItemName").gameObject;
    12.             Vector3 pos = panel.transform.position;
    13.             panel.SetActive(true);
    14.             if(x >= 1)
    15.             {
    16.                 pos.x = (panel.transform.position.x + 310);
    17.                 Debug.Log(panel.transform.position + " : " + pos);
    18.             }
    19.             panel.transform.position = pos;
    20.             TextMeshPro tmpDescription = description.GetComponent<TextMeshPro>();
    21.             tmpDescription.text = selectableObject.description;
    22.             x++;
    23.         }
    I also have here the message recieved by console:
     
    Last edited: Jun 6, 2022
  2. DaPizzaKing

    DaPizzaKing

    Joined:
    Jan 14, 2016
    Posts:
    9
    SOLUTION:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5. using TMPro;
    6.  
    7. public class BuildMenu : MonoBehaviour
    8. {
    9.     public Canvas canvas;
    10.     public GameObject objectPanel, preview, description, cost, resource, itemName;
    11.     public List<ScriptableObject> basics;
    12.     private SelectableObject selectableObject;
    13.     // Start is called before the first frame update
    14.     void Start()
    15.     {
    16.         canvas = GetComponent<Canvas>();
    17.         objectPanel = canvas.transform.Find("ObjectPanel").gameObject;
    18.         BasicsPanel();
    19.     }
    20.  
    21.     // Update is called once per frame
    22.     void Update()
    23.     {
    24.     }
    25.  
    26.     public void BasicsPanel()
    27.     {
    28.         int x = 0;
    29.         foreach (ScriptableObject scriptable in basics)
    30.         {
    31.             //Assigns all variables to the new panel being creates
    32.             GameObject panel = Instantiate(objectPanel, canvas.transform);
    33.             selectableObject = Resources.Load<SelectableObject>("ScriptableObjects/" + basics[x].name);
    34.             Debug.Log(selectableObject.name + " : " + selectableObject.description);
    35.             preview = panel.transform.Find("ObjectPreview").gameObject;
    36.             description = panel.transform.Find("Description").gameObject;
    37.             cost = panel.transform.Find("TileCost").gameObject;
    38.             resource = panel.transform.Find("ResourceRequirement").gameObject;
    39.             itemName = panel.transform.Find("ItemName").gameObject;
    40.             Vector3 pos = panel.transform.position;
    41.             panel.SetActive(true);
    42.             //
    43.             //If this isn't the first panel, it moves it over so they don't overlap
    44.             if(x >= 1)
    45.             {
    46.                 pos.x = (panel.transform.position.x + 310);
    47.                 Debug.Log(panel.transform.position + " : " + pos);
    48.             }
    49.             panel.transform.position = pos;
    50.             //
    51.             //Assigns All Fields to the selected Scriptable Variables
    52.             description.GetComponent<TextMeshProUGUI>().text = selectableObject.description;
    53.             itemName.GetComponent<TextMeshProUGUI>().text = selectableObject.itemName;
    54.             preview.GetComponent<Image>().sprite = selectableObject.preview;
    55.             cost.GetComponent<TextMeshProUGUI>().text = selectableObject.costToBuild.ToString();
    56.             resource.GetComponent<Image>().sprite = selectableObject.resourceImage;
    57.             //Adds 1 to X so the next scriptable in line is added
    58.             x++;
    59.         }
    60.     }
    61. }
    62.  
    Turns out the correct way to declare a TMP is to use the TextMeshProUGUI identifier :/
     
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    39,489
    Why do you have a public list of these things on line 11, then you load one by name on line 33... why not just ... use it!

    Code (csharp):
    1. selectableObject = basics[x];
    Also, you need to seriously break those hairy lines of code up!!

    If you have more than one or two dots (.) in a single statement, you're just being mean to yourself.

    How to break down hairy lines of code:

    http://plbm.com/?p=248

    Break it up, practice social distancing in your code, one thing per line please.

    "Programming is hard enough without making it harder for ourselves." - angrypenguin on Unity3D forums

    For future reference, there's only three steps and it's always the same three steps:

    How to fix a NullReferenceException error

    https://forum.unity.com/threads/how-to-fix-a-nullreferenceexception-error.1230297/

    Steps to success:
    - Identify what is null
    - Identify why it is null
    - Fix that