Search Unity

[QUESTION] - How do I do multi-dimensional text key array?

Discussion in 'Scripting' started by whousthat, Feb 9, 2016.

  1. whousthat

    whousthat

    Joined:
    Mar 8, 2015
    Posts:
    8
    Hi!

    I come from a PHP background and I also have a pen & paper RPG. I have a basic character creator in PHP, but it's very limited. So I figured I'd try with Unity/C#.

    First problem I ran into, I have no idea how to do arrays and I can't seem to find what I want after a few hours of searching. Closest answer I came to is "dictionary".

    Here's an example of my array in PHP, where I define my races. (this is just a small sample).

    Code (CSharp):
    1. $race["Human"]["Primary Attributes"]["Strength"]["BAS"] = 10;
    2. $race["Human"]["Primary Attributes"]["Strength"]["QTY"]  = 1;
    3. $race["Human"]["Primary Attributes"]["Strength"]["DIE"] = 6;
    4. $race["Elf"]["Primary Attributes"]["Strength"]["BAS"] = 7;
    5. $race["Elf"]["Primary Attributes"]["Strength"]["QTY"]  = 1;
    6. $race["Elf"]["Primary Attributes"]["Strength"]["DIE"] = 6;
    NOTE: The above would translate to 10 + 1D6 for the human.

    At character creation, I have a dropdown box that returns the desired race. So when I create the character, I have do something like this
    Code (CSharp):
    1. foreach ($race[$race_dropdown] as $category => $category_array) {
    2.     foreach ($category_array as $attribute_name => $attribute_array) {
    3.         foreach ($attribute_array as $name => $value) {
    4.             // Display attribute as follows Strength (10+1D6)
    5.            // bla bla bla do other stuff
    6.       }
    7.    }
    8. }
    So if I have a skill that affects strength, I can look it up easily by calling $character["Primary Attributes"]["Strength"]

    How do I do that in Unity/C#??

    Thanks again for the help :)
     
  2. Hyblademin

    Hyblademin

    Joined:
    Oct 14, 2013
    Posts:
    725
    In C# you can define arrays like

    Code (CSharp):
    1. String[] races = new String[10];
    This would create a String array with 10 elements, indexed from 0 to 9.

    In C#, it's probably better to use a list:

    Code (CSharp):
    1. List<String> races = new List<string>();
    You don't need to dimension a size, and lists have a ton of functions that make them more useful than arrays. Both lists and arrays can be indexed the same way, e.g. races.

    For what you're doing, you'll probably want to write a Race class which includes various information on rolling, stats, etc. and then make a list of Race objects:

    Code (CSharp):
    1. List<Race> races = new List<Race>();
    Then populate with Race objects appropriately. This is a thorough resource on how classes work in C#, just in case you need a how-to. In Unity, every script you create is its own class (which is more obvious when scripting in C#, but went over my head for a while as I started with JavaScript), so you would simply create a C# script, name it Race, then write in your variables and methods and one or more constructor.
     
    Last edited: Feb 9, 2016
  3. SlyRipper

    SlyRipper

    Joined:
    Jun 19, 2012
    Posts:
    251
    In C# you usually don't use arrays or dictionaries for such things.. the correct way would be to create classes for it.. for example

    Code (CSharp):
    1. class Human
    2. {
    3.     public int Strength {get; set;}
    4.     public int Agility {get; set;}
    5. }
    you can then just create instances of the class and fill those variables and (re-)use them.. much more efficient than loads of big lists/arrays/etc to access.

    If you want to make it more programmer friendly use an interface, for example

    Code (CSharp):
    1. interface Humanoid
    2. {
    3.     public int Strength {get;}
    4.     public int Agility {get; }
    5. }
    and you can reuse it for all your races, because every race that uses that interface needs to implement those variables, so you make sure they exist for later use:
    Code (CSharp):
    1. class Human : Humanoid
    2. {
    3.     public int Strength {get; set;}
    4.     public int Agility {get; set;}
    5. }
    6.  
    7. class Elf: Humanoid
    8. {
    9.     public int Strength {get; set;}
    10.     public int Agility {get; set;}
    11. }
     
  4. whousthat

    whousthat

    Joined:
    Mar 8, 2015
    Posts:
    8
    Thanks for both your answers :)

    I'll look into lists, as I find it is easier to define lists.

    So if I understand, I could create an "attribute" class and have that be part of a "race" class?

    Code (CSharp):
    1. class _attribute_interface {
    2.     public string _name {get;}
    3.     public int _base {get;}
    4.     public int _qty {get;}
    5.     public int _die {get;}
    6. }
    I'm not sure I'm understanding right though... I'm watching the Unity tutorial on Interfaces now.
     
  5. SlyRipper

    SlyRipper

    Joined:
    Jun 19, 2012
    Posts:
    251
    The interface is mainly the plan for your classes, so it describes how they should look like, to make sure every class that implements that interface has certain properties or functions, that's all. The other good effect is polymorphism, as I've shown it with human and elf, you can still create both with just that interface, and it would be enough to create a list of that interface and store human, elf, whatever class implements that interface into it.. so it's way more dynamic to use, than just a list ;-)

    so for your example you could do this for a simple race system:

    Code (CSharp):
    1. public interface IAttribute
    2. {
    3.     int Basis {get;}
    4.     int Qty {get;}
    5.     int Die {get;}
    6. }
    7.  
    8. public interface IRace
    9. {
    10.     string Name {get; }
    11.     IAttribute Attributes { get; }
    12. }
    13.  
    14. public class Attribute : IAttribute
    15. {
    16.     public int Basis {get; set;}
    17.     public int Qty {get; set;}
    18.     public int Die {get; set;}
    19.  
    20.     public Attribute(int basis, int qty, int die)
    21.     {
    22.         Basis = basis;
    23.         Qty = qty;
    24.         Die = die;
    25.     }
    26. }
    27.  
    28. public class Human : IRace
    29. {
    30.     public string Name {get; private set;}
    31.     public IAttribute Attributes {get; private set;}
    32.  
    33.     public Human(string Name)
    34.     {
    35.         Name = name;
    36.         Attributes = new Attribute(10, 1,3);
    37.     }
    38. }
    39.  
    40. public class Elf : IRace
    41. {
    42.     public string Name {get; private set;}
    43.     public IAttribute Attributes {get; private set;}
    44.  
    45.     public Elf(string Name)
    46.     {
    47.         Name = name;
    48.         Attributes = new Attribute(10, 1,3);
    49.     }
    50. }
    and later you can store them in simple lists/arrays whatever to use them..

    Code (CSharp):
    1. public class Test : MonoBehaviour
    2. {
    3.     private List<IRace> _races = new List<IRace>();
    4.  
    5.     Start()
    6.     {
    7.         var human = new Human("Pete");
    8.         var elf = new Elf("Arwen");
    9.  
    10.         _races.Add(human);
    11.         _races.Add(elf);
    12.  
    13.         _races[0].Attributes.Qty = 2;
    14.         var basis = _races[1].Attributes.Basis;
    15.         // more code..
    16.     }
    17. }
     
    Last edited: Feb 10, 2016