Problem : object is "null" only in one function...

Hey,

I have actually a problem with my code that I just don’t understand : I defined a variable “cookingcontroller” that contain a script. I use this object in a function before - “ReadingAndWriteInSlider”, and it work perfectly. But in the second function, it just don’t work… Here is my code :

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

public class RecipesBook : MonoBehaviour {

    // Bools
    public bool ShowAll = true;
    public bool ShowSweet;
    public bool ShowBitter;
    public bool ShowSour;
    public bool ShowSpicy;
    public bool ShowStarry;

    // References
    private CookingSystem cookingcontroller;
    private SaveWriteJSON saveJSONcontroller;

    public Dropdown changer;
    public GameObject ButtonMeal;

    public Image MealPortrait;
    public Text MealName;
    public Text MealTaste;
    public Text SugarRate;
    public Text SaltRate;
    public Text FatRate;
    public Text MeatRate;
    public Text DamageInfo;

    void Start () {
        cookingcontroller = gameObject.GetComponentInParent<CookingSystem>();
        saveJSONcontroller = gameObject.GetComponentInParent<SaveWriteJSON>();
    }

    public void ChangePreferenceElements () {
        if (changer.value == 0) {
            ShowAll = true;
            ShowSweet = false;
            ShowBitter = false;
            ShowSour = false;
            ShowSpicy = false;
            ShowStarry = false;
        } else if (changer.value == 1) {
            ShowAll = false;
            ShowSweet = true;
            ShowBitter = false;
            ShowSour = false;
            ShowSpicy = false;
            ShowStarry = false;
        } else if (changer.value == 2) {
            ShowAll = false;
            ShowSweet = false;
            ShowBitter = true;
            ShowSour = false;
            ShowSpicy = false;
            ShowStarry = false;
        } else if (changer.value == 3) {
            ShowAll = false;
            ShowSweet = false;
            ShowBitter = false;
            ShowSour = true;
            ShowSpicy = false;
            ShowStarry = false;
        } else if (changer.value == 4) {
            ShowAll = false;
            ShowSweet = false;
            ShowBitter = false;
            ShowSour = false;
            ShowSpicy = true;
            ShowStarry = false;
        } else if (changer.value == 5) {
            ShowAll = false;
            ShowSweet = false;
            ShowBitter = false;
            ShowSour = false;
            ShowSpicy = false;
            ShowStarry = true;
        }

        ReadingAndWriteInSlider ();
    }

    void ReadingAndWriteInSlider () {
        foreach(GameObject go in GameObject.FindGameObjectsWithTag("TagMeal")){
            Destroy (go);
        }

        int InstantiatedButton = 0;

        for (int i = 0; i < cookingcontroller.RecipesList.recipes.Count; i++) {
            bool CanBeBaked = true;

            if (cookingcontroller.RecipesList.recipes[i].IceCream > 0 && saveJSONcontroller.SaveData.slot[0].UnlockedIceCream == false) { CanBeBaked = false; }
            if (cookingcontroller.RecipesList.recipes[i].Caramel > 0 && saveJSONcontroller.SaveData.slot[0].UnlockedCaramel == false) { CanBeBaked = false; }
            if (cookingcontroller.RecipesList.recipes[i].Pomelo > 0 && saveJSONcontroller.SaveData.slot[0].UnlockedPomelo == false) { CanBeBaked = false; }
            if (cookingcontroller.RecipesList.recipes[i].Carrot > 0 && saveJSONcontroller.SaveData.slot[0].UnlockedCarrot == false) { CanBeBaked = false; }
            if (cookingcontroller.RecipesList.recipes[i].Cherry > 0 && saveJSONcontroller.SaveData.slot[0].UnlockedCherry == false) { CanBeBaked = false; }
            if (cookingcontroller.RecipesList.recipes[i].Mint > 0 && saveJSONcontroller.SaveData.slot[0].UnlockedMint == false) { CanBeBaked = false; }
            if (cookingcontroller.RecipesList.recipes[i].Honey > 0 && saveJSONcontroller.SaveData.slot[0].UnlockedHoney == false) { CanBeBaked = false; }
            if (cookingcontroller.RecipesList.recipes[i].PeanutButter > 0 && saveJSONcontroller.SaveData.slot[0].UnlockedPeanutButter == false) { CanBeBaked = false; }
            if (cookingcontroller.RecipesList.recipes[i].Coffee > 0 && saveJSONcontroller.SaveData.slot[0].UnlockedCoffee == false) { CanBeBaked = false; }
            if (cookingcontroller.RecipesList.recipes[i].Watermelon > 0 && saveJSONcontroller.SaveData.slot[0].UnlockedWatermelon == false) { CanBeBaked = false; }
            if (cookingcontroller.RecipesList.recipes[i].Wasabi > 0 && saveJSONcontroller.SaveData.slot[0].UnlockedWasabi == false) { CanBeBaked = false; }
            if (cookingcontroller.RecipesList.recipes[i].Yuzu > 0 && saveJSONcontroller.SaveData.slot[0].UnlockedYuzu == false) { CanBeBaked = false; }

            if (!ShowAll) {
                if (ShowSweet && cookingcontroller.RecipesList.recipes[i].Sweet == false) { CanBeBaked = false; }
                if (ShowBitter && cookingcontroller.RecipesList.recipes[i].Bitter == false) { CanBeBaked = false; }
                if (ShowSour && cookingcontroller.RecipesList.recipes[i].Sour == false) { CanBeBaked = false; }
                if (ShowSpicy && cookingcontroller.RecipesList.recipes[i].Spicy == false) { CanBeBaked = false; }
                if (ShowStarry && cookingcontroller.RecipesList.recipes[i].Starry == false) { CanBeBaked = false; }
            }

            if (CanBeBaked == true) {
                GameObject InstantiatedButtonMeal = Instantiate(ButtonMeal) as GameObject;
                InstantiatedButtonMeal.transform.parent = GameObject.FindGameObjectWithTag("RecipeListContainer").transform;
                if (InstantiatedButton == 0) {
                    InstantiatedButtonMeal.GetComponent<RectTransform>().anchoredPosition = new Vector2 (0, -15);
                } else {
                    InstantiatedButtonMeal.GetComponent<RectTransform>().anchoredPosition = new Vector2 (0, -(25*InstantiatedButton)-15);
                }
                InstantiatedButtonMeal.transform.GetChild(0).GetComponent <Text>().text = cookingcontroller.RecipesList.recipes[i].Name;
                InstantiatedButtonMeal.GetComponent <RecipesBookButton>().IDMeal = i;

                InstantiatedButton ++;
            }
        }
    }

    public void SeeThisRecipes (int RecipeID) {
        MealPortrait.GetComponent<Image>().sprite = Resources.Load<Sprite>(cookingcontroller.RecipesList.recipes[RecipeID].AtlasImage);
        MealName.text = cookingcontroller.RecipesList.recipes[RecipeID].Name;
        //MealTaste.text = cookingcontroller.RecipesList.recipes[RecipeID].;
        SugarRate.text = cookingcontroller.RecipesList.recipes[RecipeID].RateSugar + "%";
        SaltRate.text = cookingcontroller.RecipesList.recipes[RecipeID].RateSalt + "%";
        FatRate.text = cookingcontroller.RecipesList.recipes[RecipeID].RateFat + "%";
        MeatRate.text = cookingcontroller.RecipesList.recipes[RecipeID].RateMeat + "%";
        DamageInfo.text = cookingcontroller.RecipesList.recipes[RecipeID].DamagePoint + " (on monsters only)";
    }

}

And here is the code that call the function SeeThisRecipes :

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

public class RecipesBookButton : MonoBehaviour {

    // Ints
    public int IDMeal;

    // References
    public GameObject accesstobookcontroller;

    void Start() {
        Button btn = gameObject.GetComponent<Button>();
        btn.onClick.AddListener(TaskOnClick);
    }

    void TaskOnClick() {
        accesstobookcontroller.GetComponent <RecipesBook>().SeeThisRecipes(IDMeal);
    }

}

I have an error at this line : “MealPortrait.GetComponent().sprite = Resources.Load(cookingcontroller.RecipesList.recipes[RecipeID].AtlasImage);”, and it’s because “cookingcontroller” is null, but i just don’t understand why…

Copy and post the error you are getting as well. Thanks.

Hi ! Here is the error code :

hmm…ok. So you click a button and it calls that method. Got it. Are you certain it’s cookingcontroller that is null and not something else you are accessing? You’re accessing A few things in cookingcontroller which could also be null.

cookingcontroller isn’t just suddenly going to be null. So if it has a value after you assign it in start, then it will have that value if you aren’t changing it.

Well I’ve done a Debug.Log(cookingcontroller); wich tells me cookingcontroller is null, so I asume this is the error…

Do you perhaps have two copies of your script in the scene?

Of the cooking recipes ? No, I only have one

Is the thing cookingController is attached to also tagged as “TagMeal”?

For CookingSystems or RecipesBook.

They are only one reference of this in the scene

Nop the cookingcontroller is not attached to the objects tagged “tag meal” - these are buttons

here is what I would do for testing
set the CookingSystem to [SerializeField] to view it in unity editor
and put in a small if statement to

    // References
    [SerializeField]
    private CookingSystem cookingcontroller;
    [SerializeField]
    private SaveWriteJSON saveJSONcontroller;

void Start () {
        cookingcontroller = gameObject.GetComponentInParent<CookingSystem>();
        saveJSONcontroller = gameObject.GetComponentInParent<SaveWriteJSON>();
        if(cookingcontroller == null)
        {
            Debug.Log("failed to set cookingcontroller, via Start");
        }
    }

I’ve just done it and I don’t have “failed to set cookingcontroller, via Start” on my console so cookingcontroller is not null. I also see that cookingcontroller exist when I click on the button and that it’s supposed to do the SeeThisRecipes () function

He does mention it works in the other method, which is why it felt like it was a duplicate script error as if one copy was off, but hooked in, then the start wouldn’t execute, which would make cookingcontroller null in one copy of the script but not the other.

So, if it’s not a duplicate script error, then you need to see at what point cookingcontroller becomes null.

You can also add a Debug.Log(“cookingController is null here”, gameObject); right before the line that creates your null error. Then you can click on that debug message in the console to take you to the gameobject.

I’ve more or less already done it, accessing to cookingcontroller is just impossible, like I’ve replace all the SeeThisRecipes () function with only a Debug.Log (cookingcontroller); and a Debug.Log (cookingcontroller.WantSour) (a bool in the script CookingSystem)… And unity just don’t access to cookingcontroller, just in this function (it works in all other function and never become null in the unity inspector / editor)…

you need to brake down each of the peace’s and find out with is null,

MealPortrait.GetComponent().sprite //does it find the Image component? this might need to SpriteRender

Resources.Load(cookingcontroller.RecipesList.recipes[RecipeID].AtlasImage); //is AtlasImage a typo?
Resources.Load() needs a string. it’s the directory path and filename of the image you are using. IE : Resources.Load(“Sprites/misc/backgrounds/wallBackground1.png”);

do a Debug.Log(cookingcontroller.RecipesList.recipes[RecipeID].AtlasImage); to see what path it’s using

my bad it’s not the file name, just the directory

Resources.Load will search for a directory in Assets/Resources.

If you want to put it to Sprites directory then put it inside Resources (ex. Assets/Resources/Sprites).

Then you can just load it like this:

Sprite myFruit = Resources.Load (“Sprites/Graphics_3”);

It find everything except the cookingcontroller. Debug.Log(cookingcontroller.RecipesList.recipes[RecipeID].AtlasImage); lead to the same error. I know this line of code work pretty well - I’ve already tested it outside the code with a static RecipeID (wich is 0)

Also I just tried something, displaying a variable bool that is on the script : it just display on the console the INITIAL value of the bool. If I change this value and then call the function, it still display “false” despite the fact it’s true. I just don’t understand what’s going on with the function, I may have an idea, i’ll try to check if if I call the at start and on the update function, it work or not… ?

Ok so i’ve tried. Calling the function without clicking on the button (like I’ve added a SeeThisRecipes (0); to the ReadingAndWriteInSlider function - It work. So I now assume that it’s the RecipesBookButton script that provoke the error…

So using this debug
Debug.Log(“cookingController is null here”, gameObject); //Note the added gameObject part

When it prints it targets the proper gameobject and cookingcontroller isn’t null but when you debug cookingcontroller right after, cookingcontroller is null?

If you are getting default values in this method but you change it elsewhere, it still points to a duplicate script error. Basically working with two instances of the script.

accesstobookcontroller.GetComponent <RecipesBook>().SeeThisRecipes(IDMeal); Means this RecipesBook is probably not the same one that you are calling elsewhere.

Ok. You’r a genius & you’r true. I’ve just changed the RecipesBookButton code to be :
GameObject.FindWithTag(“GameController”).GetComponent ().SeeThisRecipes(IDMeal);

And it work. The problem was that RecipesBookButton looked for a GameController object that wasn’t instantiated and not the one that is one the scene.

Thank everyone for your help !