Search Unity

Resolved Getter and setter issue

Discussion in 'Scripting' started by Magnilum, Sep 23, 2021.

  1. Magnilum

    Magnilum

    Joined:
    Jul 1, 2019
    Posts:
    241
    Hi, I am struggling with some thing I am not sure to really understand it. Here is my code and my issue:

    Code (CSharp):
    1.     public Armor helmet;
    2.     public Armor shoulder;
    3.     public Armor chest;
    4.     public Armor belt;
    5.     public Armor[] armors { get { return new Armor[] { helmet, shoulder, chest, belt }; } }
    6.  
    7.     public void SetArmor(Armor armor, int index)
    8.     {
    9.         armors[index] = armor;
    10.         print(armors[index]);
    11.     }
    The result is null, I guess it's because of the getter which get but doesn't set.

    Do you have any idea to achieve that without a multiple " if " statement ?
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,909
    This getter creates a completely new array every single time you call it:
    Code (CSharp):
    1. public Armor[] armors { get { return new Armor[] { helmet, shoulder, chest, belt }; } }
    2.  
    So when you do this:
    Code (CSharp):
    1. armors[index] = armor;
    you are actually creating a completely new array, assigning one of the values of that array to something, and then discarding that new array.
    Next you do this:
    Code (CSharp):
    1. print(armors[index]);
    this creates a brand new array again, populated from your four fields, and prints one of them, which I guess is null because you never assigned those fields to anything.
     
    Magnilum and Bunny83 like this.
  3. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,909
    An approach that might actually work is something like this:
    Code (CSharp):
    1. public Armor[] armors = new Armor[4];
    2. public Armor helmet {
    3.   get => armors[0];
    4.   set => armors[0] = value;
    5. }
    6. public Armor shoulder {
    7.   get => armors[1];
    8.   set => armors[1] = value;
    9. }
    10. public Armor chest {
    11.   get => armors[2];
    12.   set => armors[2] = value;
    13. }
    14. public Armor belt {
    15.   get => armors[3];
    16.   set => armors[3] = value;
    17. }
     
    Magnilum and Bunny83 like this.
  4. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,999
    PraetorBlue likes this.
  5. SunnyValleyStudio

    SunnyValleyStudio

    Joined:
    Mar 24, 2017
    Posts:
    67
    Hey!
    I think that the problem is that an array isn't a great solution to store this kind or Armor set. I would advice you to try a more object oriented approach (although I am using here enums that are a bit more easy to use but less maintainable):
    Code (CSharp):
    1. public class ArmorSet
    2. {
    3.     //Data storage
    4.     Dictionary<ArmorType, Armor> armorSetDict = new Dictionary<ArmorType, Armor>();
    5.     //Get all the armors (ex to loop through). Use LINQ ToList() to convet it if needed it.
    6.     public IEnumerable<Armor> GetArmorList => armorSetDict.Values;
    7.    
    8.     /// <summary>
    9.     /// Sets or updates Armor to a given Armor piece
    10.     /// </summary>
    11.     /// <param name="armor">Armor to add or update</param>
    12.     public void AddArmor(Armor armor)
    13.     {
    14.         if (armor == null)
    15.             return;
    16.         armorSetDict[armor.ArmourType] = armor;
    17.     }
    18.     /// <summary>
    19.     /// Returns Armrom object if exists in the dict. Otherwise rteturns null.
    20.     /// </summary>
    21.     /// <param name="armorType">Armor type to access</param>
    22.     /// <returns></returns>
    23.     public Armor Get(ArmorType armorType)
    24.     {
    25.         Armor armorPiece = null;
    26.         armorSetDict.TryGetValue(armorType, out armorPiece);
    27.         return armorPiece;
    28.     }
    29. }
    30.  
    31. public class Armor
    32. {
    33.     public ArmorType ArmourType { get;}
    34.     public int Stats { get; private set; }
    35.  
    36.     public Armor(ArmorType type, int stats)
    37.     {
    38.         this.ArmourType = type;
    39.         this.Stats = stats;
    40.     }
    41. }
    42.  
    43. public enum ArmorType
    44. {
    45.     helmet,
    46.     shoulders,
    47.     chest,
    48.     belt
    49. }
    This way you can always add a new enum (different armor type) and it will still work.
    You can now save the armor type in the Armor object instead of defining each type separately and a Dictionary is a pretty fast way to access anything that you might want.

    I hope it helps!
     
  6. Magnilum

    Magnilum

    Joined:
    Jul 1, 2019
    Posts:
    241
    Thank you all for your fast response and your time, I am going to use the way upper, It's the closest to what I want to do.