扩展时,检查员引用的Unity枚举出现故障

本文关键字:枚举 故障 Unity 检查员 引用 扩展 | 更新日期: 2023-09-27 18:25:29

问题:

当enum在引用的索引之前添加了新条目时,游戏对象脚本通过检查器变量引用的enum会出现故障。

详细信息:

因此,我有多个系统,如项目列表、本地化字符串等,它们是通过解析外部文件动态构建的。此解析创建枚举,用于通过脚本检查器变量引用游戏对象的项。以下是我的本地化系统解析的输出作为示例:

    public enum LocaleID 
    {
        LocalisedStrings_ENGB,
        LocalisedStrings_ENUS,
        //...
        MAX,
    }
    public enum StringID 
    {
        String_EMPTY,
        String_Inventory,
        String_Recipes,
        String_Tools,
        String_Journal,
        //...
    }
public static class LocalisedStrings
{
    private static string[] SCLocalisedStrings_ENGB = 
    {
        "",
        "Inventory",
        "Recipes",
        "Tools",
        "Journal",
        //...
    }
    private static LocaleID currentLocale = (LocaleID)0;
    private static string[] activeSC = SCLocalisedStrings_ENGB;
    public static void SetLocale(LocaleID newLocale)
    {
        currentLocale = newLocale;
        switch(newLocale)
        {
            case LocaleID.LocalisedStrings_ENGB:
                activeSC = SCLocalisedStrings_ENGB;
            break;
            case LocaleID.LocalisedStrings_ENUS:
                activeSC = SCLocalisedStrings_ENUS;
            break;
        }
    }
    //entry interface: 
    public static string Get(StringID stringID)
    {
        return activeSC[(int)stringID];
    }
}

这只是通过基于设置区域设置的枚举索引返回字符串。所以我会把一个NPC的名字暴露在一个角色上:

[SerializeField]
public StringID SpeakerTitle;

并通过检查员设置。

这个问题是显而易见的,也是意料之中的问题-如果枚举的解析方式不同,例如,在顶部添加一个额外的条目(例如用于排序)或删除(用于清理过时的条目),那么所有引用的枚举都将乱序1个点,因为它们将引用枚举条目的索引。

一个简单的解决方案是强制执行一条规则,即只添加到末尾,从不删除过时的条目。这变得相当浪费,所以显然不是很好。

对这个问题有什么建议的解决方案?有其他人如何处理这种相当常见的情况的例子吗?当然,我更喜欢可以排序并在任何地方添加新条目的东西,但我们不能拥有我们想要的一切:)

扩展时,检查员引用的Unity枚举出现故障

只需为条目指定显式数值:

public enum StringID 
{
    String_EMPTY = 0,
    String_Inventory = 1,
    String_Recipes = 2,
    String_Tools = 3,
    String_Journal = 4,
    //...
}

这样,排序与值完全无关。请注意,当你需要做出突破性的改变时,你可以回顾性地或以"及时"的方式来做这件事。

(我个人也会去掉String_前缀,但那是另一回事。)

我会使用显式映射,而不是裸数组;例如:

private static Dictionary<StringID,string> SCLocalisedStrings_ENGB = 
    new Dictionary<StringID,string>
{
    {StringID.String_EMPTY, ""},
    {StringID.String_Inventory, "Inventory"},
    //...
};

并通过以下方式获取价值:

string val;
return LocaleStrings.TryGetValue(key, out val) ? val : DefaultStrings[key];

嗯。。。实际上,我可能会将外部文件中的翻译作为键/值对,但是。。。嗯。

注意:您总是可以字典数据放回有序数组中;但是具有显式映射可以防止顺序发生混乱。