【问题标题】:Wrong Enum index when serializing an Enum field (Unity)序列化枚举字段时错误的枚举索引(Unity)
【发布时间】:2021-07-24 13:08:18
【问题描述】:

在 Unity3D 中,我有两个枚举:

public enum GlobalColor
{
    Player,
    PlayerFX1,
    PlayerFX2,
    Ennemy,
    EnnemyFX1,
    EnnemyFX2,
    Background,
    BackgroundParticles1,
    BackgroundParticles2,
    Button,
    InactiveButton
}
public enum ColorName
{
    Player,
    PlayerFX1,
    PlayerFX2,
    Ennemy_1,
    EnnemyFX1_1,
    EnnemyFX2_1,
    Ennemy_2,
    EnnemyFX1_2,
    EnnemyFX2_2,
    Ennemy_3,
    EnnemyFX1_3,
    EnnemyFX2_3,
    Background,
    BackgroundParticles1,
    BackgroundParticles2,
    Button,
    InactiveButton
}

ColorName 用于创建调色板(每个 Enum 元素对应于我的游戏中的特定颜色), GlobalColor 用于将颜色附加到 GameObjects,Ennemy 只出现一次,因为敌人的颜色是在 ColorName 的三者之间随机选择的。 在通用 ColoriseBase 脚本中(它是所有 Colorise 脚本的基础,负责根据当前调色板的颜色为不同的组件着色,存在 ColoriseSprite、ColoriseParticleSystem 和 ColoriseCamera,都继承自 ColoriseBase)我有以下代码: [SerializeField] private GlobalColor color; 能够直接在检查器中选择我的组件的颜色。 要将此 GlobalColor 转换为 ColorName(以在当前调色板中找到正确的颜色),我正在使用反射:

protected ColorName GlobalColorToColorName(GlobalColor color)
{
    string randomEnnemy = "";
    if (color == Ennemy || color == EnnemyFX1 || color == EnnemyFX2)
    {
        EnnemyIdentity ennemyIdentity = GetComponentInParent<EnnemyIdentity>();
        if (ennemyIdentity != null)
            randomEnnemy = string.Format("_%s", ennemyIdentity.EnnemyType.ToString());
        else
            throw new MissingComponentException("An ennemy needs to have an EnnemyIdentity script attached to it.");
    }
    print(Enum.GetName(typeof(GlobalColor), color));
    string name = Enum.GetName(typeof(GlobalColor), color);
    var type = typeof(ColorName);
    return (ColorName)type.GetProperty(name + randomEnnemy).GetValue(null);
}

print 方法用于调试目的。但是,当我启动我的游戏时抛出异常:

NullReferenceException: Object reference not set to an instance of an object
ColoriseBase`1[E].GlobalColorToColorName (GlobalColor color) (at Assets/Scripts/Color/ColoriseBase.cs:56)
ColoriseBase`1[E].get_Color () (at Assets/Scripts/Color/ColoriseBase.cs:10)

我试图找出错误,我发现我的变量 GlobalColor colorin ColoriseBase 不等于我在检查器中给出的值。如果在检查器中我将其初始化为 Player(which index == 0),则此变量的索引为 12,GlobalColor 的任何成员都没有此索引,这会导致异常。

【问题讨论】:

  • 需要说明如何调用GlobalColorToColorName。根据错误,您没有将参数 GlobalColor color 传递给方法
  • @rustyBucketBay 不,需要是别的东西。 GlobalColorenum(值类型),因此永远不能是 null

标签: c# unity3d serialization enums


【解决方案1】:

不是 100%,但很确定错误来自

type.GetProperty

由于您的类型是enum,它没有属性,只有值。这很可能会返回null,因此后来GetValue 会导致异常。

您可能更愿意使用Enum.Parse&lt;TEnum&gt;(string),例如(假设其余部分按预期工作)

return Enum.Parse<ColorName>(name + randomEnnemy);

对于未来的问题和问题:请指出异常是从哪一行引发的。

一般来说,出于调试目的,请避免像您在

中那样使用更长的链式访问
return (ColorName)type.GetProperty(name + randomEnnemy).GetValue(null);

将所有内容放在一行中,您将一无所获,除非如前所述,调试它会更糟。你也可以这样写

var fullName = name + randomEnnemy;
var property = type.GetProperty(fullName);
return (ColorName) property.GetValue(null);

但是通过这种方式,您可以更好地调试Debugging your code with breakpoints 时失败的确切位置

【讨论】:

    【解决方案2】:

    谢谢derHugo我找到了解决办法,这是我的新GlobalColorToColorNamemethod:

    
    protected ColorName GlobalColorToColorName(GlobalColor color)
    {
        string name = color.ToString();
        if (color == Ennemy || color == EnnemyFX1 || color == EnnemyFX2)
        {
            string randomEnnemy;
            EnnemyIdentity ennemyIdentity = GetComponentInParent<EnnemyIdentity>();
            if (ennemyIdentity != null)
                randomEnnemy = string.Format("_%s", ennemyIdentity.EnnemyType.ToString());
            else
                throw new MissingComponentException("An ennemy needs to have an EnnemyIdentity script attached to it.");
            name += randomEnnemy;
        }
        return (ColorName)Enum.Parse(typeof(ColorName), name);
    }
    

    【讨论】:

    • 您真的应该使用我在回答中显示的通用版本;)Enum.Parse&lt;ColorName&gt;(name + randomEnnemy);
    • 非常感谢,但您的意思是 Enum.TryParse(name, out aColorNameVariable); ? (通用)
    • 不,因为已经写了两次我的意思是Enum.Parse&lt;ColorName&gt;(name) ;) 你当然也可以使用Enum.TryParse&lt;T&gt;(string, out T) 这也是通用的是
    猜你喜欢
    • 1970-01-01
    • 2013-08-24
    • 2014-08-10
    • 1970-01-01
    • 2012-05-22
    • 1970-01-01
    • 2011-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多