为什么我不能在 Unity3D 中覆盖 "OnValidate()"?

Why can't I override "OnValidate()" in Unity3D?

所以我正在实现一个继承自 Text 的弯曲文本 class。在其中我有这个 OnValidate 实现:

protected override  void OnValidate()
{
  base.OnValidate();
  // some other code
}

现在,当我尝试构建项目时出现此错误:

error CS0115: CurvedText.OnValidate() is marked as an override but no suitable method found to override

所以我觉得这很奇怪,即使 VS 建议覆盖。那我接下来要做什么?删除 override 关键字并忽略 VS 警告。所以现在统一抛出这个错误:

error CS0117: UnityEngine.UI.Text does not contain a definition for OnValidate 

那我现在该怎么办?我还应该提到,当脚本被添加到场景中的对象时,它会按预期工作并且不会抛出任何错误。

因为OnValidate是Unity3D消息系统的一部分。

正如 this blog 提到的,此消息传递功能只会在以下情况下解决 第一次访问 MonoBehaviour 对象并通过脚本运行时(Mono 或 IL2CPP)检查底层脚本。

所以现在,对于编译器来说,没有 OnValidate 可以覆盖。

只需像这样调用方法:

void OnValidate()
{
   // some other code
}

我对评论的 2 美分

  • protected 关键字不能防止内容被覆盖。

  • virtual 关键字用于修改事物并允许它们在派生的 class 中被覆盖。这意味着您不能覆盖非虚拟方法。

如果您使用预处理器指令明确将其设为仅编辑器,则可以覆盖 OnValidate()

OnValidate() 的 Unity 文档指出“仅在编辑器中调用”: https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnValidate.html

因此,您可以通过在覆盖 OnValidate() 时使用预处理器指令 #if UNITY_EDITOR 来防止 VS 投诉和编译器错误。这也更明确地说明了代码的作用,而不是依赖于对 Unity 内部结构的洞察,因此更具可读性。

它可能作为 editor-only 代码从幕后的构建中隐藏起来,但是当它被覆盖时,这个 hack 以某种方式被破坏了。

#if UNITY_EDITOR
    protected override void OnValidate()
    {
        // Do something.
    }
#endif // UNITY_EDITOR