Home > other >  Understanding why Unity C# passing custom class object that return null pointer error
Understanding why Unity C# passing custom class object that return null pointer error

Time:11-06

can someone help me understand what I'm missing?

My problem is, I have a script that manages the scene, and when it starts up it creates a bunch of buttons from a prefab.

 void InitializeCharacters()
    {
        int index = 0;
        foreach (CharacterSelectionItem character in CharacterSelectionData.CharacterList)
        {
            CharacterButton.GetComponent<CharacterButton>().Character = character;
            CharacterButton.GetComponent<CharacterButton>().fullSource = character.FullCharacterSource;

            GameObject newButton = Instantiate(CharacterButton) as GameObject;
            newButton.transform.SetParent(CharacterPanel.transform, false);
        }
    }

CharacterButton is the prefab, assigned from editor to the script, with this script attached:

using static CharacterSelectionItem;

public class CharacterButton : MonoBehaviour
{
    public CharacterSelectionItem Character;
    public string fullSource;

    void Start()
    {
        Debug.Log("Full"   fullSource);
        Debug.Log("Character image source"   Character.FullCharacterSource);
    }
}
public class CharacterSelectionItem
{
    public string Description;
    public string ImageSource;
    public string FullCharacterSource;
    public string CharacterHistory;
    
    public CharacterSelectionItem(
     string descr,
     string img,
     string fullSource,
     string histroy,
     Race race
     )
    {
        Description = descr;
        ImageSource = img;
        FullCharacterSource = fullSource;
        CharacterHistory = histroy;
        Race = race;

    }

};

Now, the first debug prints the string, while the second returns "Object reference not set to an instance of an object", and I can't really understand why. I tried to pass character in a SetCharacter(ref CharacterSelectionItem character) to have the reference but still don't work. The objective is not to pass every field on of CharacterSelectionItem but the whole object. It's my first project in unity and I was loosely following a tutorial. and hope I could find an answer there but it didn't come. I think I'm missing something pretty basic but don't know what, can someone help?

CodePudding user response:

I had a similar situation lately and discovered that while Instantiate basically creates a deep clone of the prefab it only seems to take over custom fields that are serialized.

At least from the code you shared that wouldn't be the case for

public CharacterSelectionItem Character;

since the type CharacterSelectionItem isn't [Serializable]

Try to make it

[Serializable]
public class CharacterSelectionItem
{
    ...
}

If you then do not want it to appear in the Inspector you can still decorate the field additionally

[HideInInspector] public CharacterSelectionItem Character;

Alternatively instead of assigning the field on the prefab before Instantiate rather assign it on the instance in the first place:

var newButton = Instantiate(CharacterButton);
newButton.transform.SetParent(CharacterPanel.transform, false);
newButton.GetComponent<CharacterButton>().Character = character;
newButton.GetComponent<CharacterButton>().fullSource = character.FullCharacterSource;
  • Related