Unity:在检查器中分配抽象对象的实例

Unity: Assign instance of abstract object in the inspector

在我的游戏中,我有一个魔法系统,它使用命令模式来存储步骤。我如何在检查器中分配一个不是从 MonoBehaviorScriptableObject 派生的抽象命令(或者只是不对其进行硬编码)?

下面我有一个最小的例子,注意 SpellCommand 不是从 MonoBehaviorScriptableObject 派生的。

public abstract class SpellCommand {
    public SpellCommand (int power = -1) {
        this.power = power;
    }
    public abstract void Cast();
}

下面是咒语的样子

public class SampleSpell : SpellCommand {
    public SampleSpell(int power) : base(power: power) { }

    public override void Cast() {
        Debug.Log("Sample Spell Cast");
    }
}

最后 MonoBehavior 调用它

public class TestSpellInvoker : MonoBehaviour
{
    public SpellCommand testSpell;

    void Start() {
        testSpell.Cast();
    }
}

因为我知道 Unity 不支持不是从 MonoBehavior 派生的抽象 类 的序列化,所以我编写了自己的检查器脚本来分配和显示 testSpell 的内容,但是每当我进入了播放模式,好像被取消了。

我考虑过删除所有多态性并简单地使用一个大的 Enum 来表示 sub类,但这会引入大量的复杂性并且感觉非常违背 C# 的精神和哎呀。我也考虑过使用 ScriptableObjects,但这需要(在我的情况下)可能有数千个 ScriptableObject 实例保存为文件,然后我将不得不争论(尽管据说我的知识ScriptableObjects 非常基础,所以我可能遗漏了一些东西)。

  1. 您的摘要 class 和实现者应该是 Serializable。如果不是,您的数据将不会存储在场景或预制件中。
  2. 我没有在 MonoBehaviour 中使用过它,但它在 ScriptableObject 中有效。使用 SerializableReference 而不是 SerializableField。只要您遵循文档中的规则(可序列化,不是来自 UnityEngine.Object,不是值类型,不是字典),您就可以存储实现实例。

注意:如果这样做,您需要调整自定义检查器以根据实施者显示数据。