Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Set default value from parent variable

Discussion in 'Scripting' started by DamnICantFly, Nov 17, 2014.

  1. DamnICantFly

    DamnICantFly

    Joined:
    Sep 27, 2013
    Posts:
    12
    My goal is to get a list with weapons and ammunition in the editor.

    The problem is that I cannot initialize the standard value from itemType for each class.
    I will get the following error: "the same field name is serialized multiple times in the class or its parent class".
    I also tried this using the 'new' keyword in front of 'Item.ItemType' in 'Weapon' and 'Ammunition' but this will give me the same error.

    Code (CSharp):
    1. public class Weapon : Item
    2. {
    3.     public Item.ItemType itemType = Item.ItemType.Weapon;
    4.     public float rateOfFire;
    5.     public float accuracy;
    6. }
    7. public class Ammunition : Item
    8. {
    9.     public Item.ItemType itemType = Item.ItemType.Ammunition;
    10.     public GameObject prefab;
    11. }
    12. public class Item
    13. {
    14.     public ItemType itemType;
    15.     public enum ItemType
    16.     {
    17.         Weapon,
    18.         Ammunition
    19.     }
    20. }
    21. public class MainClass
    22. {
    23.    public List<Weapon> weaponList = new List<Weapon>();
    24.    public List<Ammunition> weaponList = new List<Ammunition>();
    25. }
    26.  
    I've read that you could also use something like this:

    Code (CSharp):
    1.  
    2. public class Ammunition : Item
    3. {
    4.     public Ammunition ()
    5.     {
    6.         itemType = Item.ItemType.Ammunition;
    7.     }
    8.     public GameObject prefab;
    9. }
    10.  
    This will work when you initialize a single variable with the 'new' keyword like this:
    Code (CSharp):
    1.  
    2. public Weapon weapon = new Weapon();
    3.  
    The problem is, I don't want 1 variable, I want a list. This could possibly be solved by initializing a list with new Weapons but I have no idea how to do that.

    Is there anyone that can help me solve this problem? :D

    Also if I'm not clear about something, just let me know and I'll try to explain it.
     
  2. arthur_fukushima

    arthur_fukushima

    Joined:
    Nov 12, 2014
    Posts:
    28
    Hi!

    I think it's because you already is declaring the variable "itemType" on your parent class, so you don't need to do this on the child classes, because they will inherit your public and protected attributes from Item class.

    Code (CSharp):
    1. public class Weapon : Item
    2. {
    3.     public float rateOfFire;
    4.     public float accuracy;
    5. }
    6. public class Ammunition : Item
    7. {
    8.     public GameObject prefab;
    9. }
    10. public class Item
    11. {
    12.     public ItemType itemType;
    13.     public enum ItemType
    14.     {
    15.         Weapon,
    16.         Ammunition
    17.     }
    18. }
    19. public class MainClass
    20. {
    21.    public List<Weapon> weaponList = new List<Weapon>();
    22.    public List<Ammunition> weaponList = new List<Ammunition>();
    23. }
    Just remove the ItemType declaration from your Ammunition and Weapon classes and the problem will be solved (I don't know if this is a bug in Unity, but in my Unity, I need to recompile the code some times, and then the error disapears...)

    o/
     
  3. DamnICantFly

    DamnICantFly

    Joined:
    Sep 27, 2013
    Posts:
    12
    If you remove the ItemType declaration from the Ammunition and Weapon classes, you won't know what type each item is. If I loop though the list's now and ask for the value from 'itemtype', it'll always return the default value (the first value from the enum ItemType --> Weapon). Which is logical cause you never set it.
     
  4. arthur_fukushima

    arthur_fukushima

    Joined:
    Nov 12, 2014
    Posts:
    28
    True, but to do this, the correct way is to set the variable value on Awake() function.

    Another way to this is to set the variable default value in the editor. (To make your class visible on the editor, just use the [System.Serializable] attribute, something like this:
    Code (CSharp):
    1. [System.Serializable]
    2. public class Item
    3. {
    4.     public ItemType itemType;
    5.     public enum ItemType
    6.     {
    7.         Weapon,
    8.         Ammunition
    9.     }
    10. }
     
  5. DamnICantFly

    DamnICantFly

    Joined:
    Sep 27, 2013
    Posts:
    12
    Using that would require me to set the itemType for each list of classes that inherits 'Item'.
    This can also give problems when one of my artists accidentally sets the itemType to a wrong value.
    Since the itemType for each class is always the same (basically a const value), it shouldn't be changeable at all.
     
  6. arthur_fukushima

    arthur_fukushima

    Joined:
    Nov 12, 2014
    Posts:
    28
    But if you declare the ItemType variable on every class that inherits Item, you are setting on every class the variable value.

    Another way to resolve this, is to set his type on the constructor.
    Code (CSharp):
    1. public class Weapon : Item
    2. {
    3.     public Weapon()
    4.     {
    5.         itemType = ItemType.Weapon;
    6.     }
    7. }
     
  7. DamnICantFly

    DamnICantFly

    Joined:
    Sep 27, 2013
    Posts:
    12
    After trying allot I've found my solution :D It's quite small and simple, you just gtta know how to use it :p
    Code (CSharp):
    1. public class Weapon : Item
    2. {
    3.     public override ItemType itemType {get{return ItemType.Weapon;}}
    4.     public float rateOfFire;
    5.     public float accuracy;
    6. }
    7. public class Ammunition : Item
    8. {
    9.     public override ItemType itemType {get{return ItemType.Ammunition;}}
    10.     public GameObject prefab;
    11. }
    12. public class Item
    13. {
    14.     public abstract ItemType itemType {get;}
    15.     public enum ItemType
    16.     {
    17.         Weapon,
    18.         Ammunition
    19.     }
    20. }
    21. public class MainClass
    22. {
    23.    public List<Weapon> weaponList = new List<Weapon>();
    24.    public List<Ammunition> weaponList = new List<Ammunition>();
    25. }
    Making the variable itemType a 'getter' allows me to make it abstract.
    Since the variable is now abstract, every class that inherits 'Item' requires the getter itemType. Since it's a get value I can just return the ItemType that I need.
     
    arthur_fukushima likes this.
  8. DamnICantFly

    DamnICantFly

    Joined:
    Sep 27, 2013
    Posts:
    12
    This indeed works if you create a Weapon using the 'new' keyword like I said in the first post. Sadly this doesn't work when using lists since it won't call the function 'Weapon()'..


    Thank you for your help btw :)
     
    Last edited: Nov 17, 2014