Search Unity

[HELP] System.Serializable isn't working

Discussion in 'Scripting' started by lordnuggetor101, Sep 21, 2019.

  1. lordnuggetor101

    lordnuggetor101

    Joined:
    Sep 13, 2017
    Posts:
    7
    For some reason the variables "TheCaptain" and "Parasite" won't show up in the unity inspector no matter if I add [System.Serializable] or [SerializeField]. Here's the entire class:

    Code (CSharp):
    1. [System.Serializable]
    2. public class BattleData {
    3.     //Initialize Sprites
    4.     public Sprite TheCaptain;
    5.     public Sprite Parasite;
    6.  
    7.     public BattleData() {
    8.        //Dictionary of enemies
    9.         Dictionary<string, Enemy> Enemies = new Dictionary<string, Enemy>() {
    10.             {"Parasite", new Enemy(Parasite, "Parasite", 25)}
    11.         };
    12.  
    13.         //Dictionary of characters
    14.         Dictionary<string, Character> Characters = new Dictionary<string, Character>() {
    15.             {"The Captain", new Character(TheCaptain, "The Captain", 100, 50)}
    16.         };
    17.     }
    18. }
     
    Last edited: Sep 21, 2019
  2. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    1,035
    Add [System.Serializable] above the class declaration.

    Also, you have a start method on there. If you intend to add this class to a gameobject then you would need to inherit from monobehaviour. If you did that, you wouldn't need to mark the class as Serializable.
     
  3. lordnuggetor101

    lordnuggetor101

    Joined:
    Sep 13, 2017
    Posts:
    7
    As I said above and in the title, I did try that (I just didn't put it in the pasted code because it wasn't working). I realize that using start is dumb but that still isn't the problem, changing my code to this:
    Code (CSharp):
    1. [System.Serializable]
    2. public class BattleData {
    3.     //Initialize Sprites
    4.     public Sprite TheCaptain;
    5.     public Sprite Parasite;
    6.  
    7.     public BattleData() {
    8.        //Dictionary of enemies
    9.         Dictionary<string, Enemy> Enemies = new Dictionary<string, Enemy>() {
    10.             {"Parasite", new Enemy(Parasite, "Parasite", 25)}
    11.         };
    12.  
    13.         //Dictionary of characters
    14.         Dictionary<string, Character> Characters = new Dictionary<string, Character>() {
    15.             {"The Captain", new Character(TheCaptain, "The Captain", 100, 50)}
    16.         };
    17.     }
    18. }
    still doesn't work
     
  4. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    1,035
    Nothing dumb about using start, I just meant that if you wanted the start method called by unity the class would have to derive from Monobehaviour and be attached to an object.

    How are you declaring your BattleData variablle in the class which is using it?
     
  5. lordnuggetor101

    lordnuggetor101

    Joined:
    Sep 13, 2017
    Posts:
    7
    I was just saying it was dumb I didn't realize I had to remove start when I didn't derive from Monobehaviour.
    This is how I'm declaring it when I use it:
    Code (CSharp):
    1. BattleData BData = new BattleData();
    In the script that references BattleData, everything works fine. Literally the only problem is the sprites not showing up in the inspector. In case it helps, the BattleData file also has some other code in it:
    Code (CSharp):
    1. public class Character {
    2.     GameObject obj;
    3.     Sprite sprite;
    4.     string name;
    5.     int maxHp;
    6.     int hp;
    7.     int maxAp;
    8.     int ap;
    9.  
    10.     public Character(Sprite _sprite, string _name, int _maxHp, int _maxAp) {
    11.         sprite = _sprite;
    12.         name = _name;
    13.         maxHp = _maxHp;
    14.         hp = maxHp;
    15.         maxAp = _maxAp;
    16.         ap = _maxAp;
    17.     }
    18.  
    19.     public void Create(Vector2 position) {
    20.         obj = new GameObject(name);
    21.         obj.transform.position = position;
    22.         obj.AddComponent(typeof(SpriteRenderer));
    23.         obj.GetComponent<SpriteRenderer>().sprite = sprite;
    24.     }
    25. }
    26.  
    27. public class Enemy {
    28.     GameObject obj;
    29.     Sprite sprite;
    30.     string name;
    31.     int maxHp;
    32.     int hp;
    33.  
    34.     public Enemy(Sprite _sprite, string _name, int _maxHp) {
    35.         sprite = _sprite;
    36.         name = _name;
    37.         maxHp = _maxHp;
    38.         hp = maxHp;
    39.     }
    40.  
    41.     public void Create(Vector2 position) {
    42.         obj = new GameObject(name);
    43.         obj.transform.position = position;
    44.         obj.AddComponent(typeof(SpriteRenderer));
    45.         obj.GetComponent<SpriteRenderer>().sprite = sprite;
    46.     }
    47. }
    I didn't include it as it seems irrelevant due to being other classes.
     
  6. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    1,035
    You don't have to remove start at all. Anyway, where do you expect them to show up the inspector? If you have a class which has a public field of BattleData, there should be a dropdown next to it with the sprites fields.
     
  7. lordnuggetor101

    lordnuggetor101

    Joined:
    Sep 13, 2017
    Posts:
    7
    UPDATE: It seems like even the example unity shows on the API doesn't work:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class SomePerson : MonoBehaviour
    4. {
    5.     //This field gets serialized because it is public.
    6.     public string firstName = "John";
    7.  
    8.     //This field does not get serialized because it is private.
    9.     private int age = 40;
    10.  
    11.     //This field gets serialized even though it is private
    12.     //because it has the SerializeField attribute applied.
    13.     [SerializeField]
    14.     private bool hasHealthPotion = true;
    15.  
    16.     void Start()
    17.     {
    18.         if (hasHealthPotion)
    19.             Debug.Log("Person's first name: " + firstName + " Person's age: " + age);
    20.     }
    21. }
    None of it shows up on the inspector. This means it has to be some bug or problem with my build. I have the latest version & tried recompling. Still no luck.
     
  8. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    1,035
    Do you have any custom editor code? When you attach the SomePerson component to a gameobject and select that gameobject, what shows in the inspector?
     
  9. lordnuggetor101

    lordnuggetor101

    Joined:
    Sep 13, 2017
    Posts:
    7
    Whoops I forgot that was a monobehaviour example.

    Either way, I tried using a simple class:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class test {
    6.     [SerializeField] public int pizza;
    7. }
    and that didn't show anything in the inspector.

    nothing that doesn't derive from monobehaviour or scriptableobject works.
     
  10. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    1,035
    Again, where do you expect them to show in the inspector? The class needs to be serializable.
     
  11. lordnuggetor101

    lordnuggetor101

    Joined:
    Sep 13, 2017
    Posts:
    7
    What do you mean where? The exact same spot where anything else would be in the inspector. If I change the script to a monobehaviour one I can see all my values, even it isn't attached to anything. If I don't, nothing shows up in the inspector. [System.Serializable] doesn't work as I said everywhere, neither does [SerializeFIeld] which does the exact same thing but for only one value if you're confused as to my above post.
     
  12. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    1,035
    Are you using the class in a script which derives from monobehaviour and is attached to a gameobject? Show a screenshot of where it should be and post the code using it.
     
  13. lordnuggetor101

    lordnuggetor101

    Joined:
    Sep 13, 2017
    Posts:
    7
    upload_2019-9-21_17-48-14.png
    upload_2019-9-21_17-49-8.png
     
  14. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    1,035
    That's why I asked where you expected to see them. There aren't meant to show there for a standard class. If you want an object you can assign sprites too either use a sciprtableobject or make a prefab with a class that has a BattleData field.