Accessible collection of Type

I’m using collection of Type inside my class and wondering how to make it accessible through inspector or editor window.

To be more specific I create some system based on enums, which takes a few Types, checks it is an enum type, gets base name of enum and it’s elements etc. For now it’s just a list fused inside of a class:
public static readonly

List<Type> EnumsToTransation =  new List<Type>
{
    (typeof(Items)),
    (typeof(Dialogs))
};

It won’t be modified to often and can be stored that way, but access through the inspector will be wery handy and “the right thing”, I guess. Thanks in advance

Ok, i see what you want to do here. However Enums aren’t great when it comes to generalization. Enums are represented by integer values (as you probably know). An enum type represents it’s own type. Is a value type (since it’s an integer) and in almost all generalizations it has to be boxed into a reference type. The System.Enum class is actually a class, not a struct.

Anyways, since i don’t know how your localization structure looks like here are some suggestions:

  • Generally you should distinguish between how the localization data is serialized and how it’s stored / used at runtime.
  • I would also suggest to not use Unity’s serialization system to actually define the localization data. If you change the structure of your classes it can happen quite easily that you loose everything you’ve entered already. It’s best to store the localization in a seperate file (JSON / XML / …). That also simplifies translation to other languages (which is usually done by external people).
  • For runtime use i would group the localization information by language, followed by the group (your System.Type) followed by the actual item. See example below.
  • For storing the information in a file it’s best to not use the enum values as it’s difficult to remember what number represents what.
  • The localization file should be read at start. If you grouped the data by language you can also only load the current language entries.

Example of a localization file:

<languages>
   <language name="english">
      <enumgroup name="Items">
         <string name="Sword">sword</string>
         <string name="Apple">apple</string>
      </enumgroup>
      <enumgroup name="MenuItem">
         <string name="NewGame">New Game</string>
         <string name="Quit">Quit Game</string>
      </enumgroup>
   </language>
   <language name="russian">
      <enumgroup name="Items">
         <string name="Sword"> ... </string>
         <string name="Apple"> ... </string>
      </enumgroup>
      <enumgroup name="MenuItem">
         <string name="NewGame"> ... </string>
         <string name="Quit"> ... </string>
      </enumgroup>
   </language>
</languages>

At runtime you might want to use a Dictionary> for your enum localization data. When you read in the localization file you could use the enumgroup’s name to either find the enum Type with System.Type.GetType or if you use namespaces (which makes it difficult to find the correct type) use your System,Type List you have defined in your question. For each type you create a dedicated dictionary which maps an enum value to a string. You can use Enum.Parse to get the actual integer value for a certain string. With that you can set the string entries in the dictionary.

To query a string value at runtime your method could look like this:

private Dictionary<System.Type, Dictionary<int, string>> localization;
private Dictionary<System.Type, Dictionary<int, string>> fallbackLocalization;

private string GetDefault(System.Enum enumEntry)
{
    var type = enumEntry.GetType();
    Dictionary<int, string> dict;
    if (!fallbackLocalization.TryGetValue(type, out dict))
        return "Localization missing";
    int val = (int)(object)enumEntry;
    string result;
    if (dict.TryGetValue(val, out result))
        return result;
    return "Localization missing";
}

public string Get(System.Enum enumEntry)
{
    var type = enumEntry.GetType();
    Dictionary<int, string> dict;
    if (!localization.TryGetValue(type, out dict))
        return GetDefault(enumEntry);
    int val = (int)(object)enumEntry;
    string result;
    if (dict.TryGetValue(val, out result))
        return result;
    return GetDefault(enumEntry);
}

Usually you have a default language that usually is ensured that it contains a localization string for everything (Doesn’t need to be english but usually it’s english ^^). The Get method here first tries to get the value from the current localization structure and if it fails it gets the value from the default localization.

If you want to load all languages you could manage them again with a dictionary like this:

private Dictionary<LocalizationLanguage, Dictionary<System.Type, Dictionary<int, string>>> localization;

All that is usually packed into a Localization class which handles all this language switching in one place.

XML is usually nicer to structure the data. However personally i would probably go with JSON as most XML parsers are quite large (in the sense of assembly size).

Another nice thing about an external loc-file is that you can ship an update / patch without rebuilding the game.