阻止在编辑器中添加组件

我正在寻找一种方法来禁用在Unity编辑器中附加我的MonoBehaviour组件的可能性。 所以我不希望我的组件出现在用户可见的任何地方。

原因是我使用AddComponent()从脚本手动附加此组件。 所以这是一个更方便的问题,我只是不希望用户认为他必须手动添加我的组件才能使我的插件正常工作。 (无论如何,这样做不会造成任何麻烦。再一次,这只是方便)

精度

我正在编写一个库(dll插件),所以我不能使用不同于我的组件命名文件的技巧,但这正是我正在寻找的效果。

我还试图简单地将我的类作为内部,因为它实际上是什么,程序集应该是唯一可以访问此组件的程序集。 但是,我害怕从MonoBehaviourinheritance,即使有内部类,也可以在编辑器中使用该组件…

HideInInspector属性似乎不适用于类。

我使用RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)从静态方法调用AddComponent ,因此我不会依赖任何其他行为。

相当挑战,如果我们找到答案,那将是奢侈品。 任何的想法? 非常感谢你

一个非常简单的解决方案是让您的类成为某个所有者的内部类:

 class NotAMonoBehaviour { class MyMonoBehaviour : MonoBehaviour { //etc. } } 

您可以轻松地添加该类:

 gameObject.AddComponent() 

并且它不会显示在检查器的“添加组件”列表中。 根据建议使用隐藏标志进行设置也会阻止它显示在检查器本身中,尽管不能完全依赖它,因为您可以在检查器中打开Debug视图并仍然看到隐藏的组件。

所以我不希望我的组件出现在用户可见的任何地方。

下面的代码段应该从编辑器(检查器和层次结构)隐藏您的脚本。

 this.hideFlags = HideFlags.HideInHierarchy; this.hideFlags = HideFlags.HideInInspector; 

我正在寻找一种方法来禁用在Unity编辑器中附加我的MonoBehaviour组件的可能性

只要您的脚本inheritance自MonoBehaviour就无法阻止人们将其附加到GameObject。

虽然,你可以这样做,当他们附加它们的GameObject时,你抛出一个错误,然后销毁该组件。 将变量设置为true。 您可以使用插件中的函数将插件中的此变量设置为true,以便您的脚本不会被破坏。

示例代码:

 public class MoveTowards : MonoBehaviour { private bool callFromMyPlugin = false; //Call from your plugin to not destroy this script public void keepAlive() { callFromMyPlugin = true; } IEnumerator Start() { //Hides component from users hideFromUser(); if (!callFromMyPlugin) { destroyThisComponent(); } yield return null; } //Hides component in the Hierarchy and Inspector void hideFromUser() { this.hideFlags = HideFlags.HideInHierarchy; this.hideFlags = HideFlags.HideInInspector; } //Destroys this component void destroyThisComponent() { Debug.LogError("You are not allowed to add this component to a GameObject"); DestroyImmediate(this); Debug.LogWarning("This component is now destroyed"); } } 

当人们这样称呼时:

 GameObject testObj = new GameObject("Test"); MoveTowards script = testObj.AddComponent(); 

他们将得到以下错误,脚本将自行销毁:

在此处输入图像描述

现在,如果你从你的插件调用create it并调用keepAlive函数,脚本应该保持:

 GameObject testObj = new GameObject("Test"); MoveTowards script = testObj.AddComponent(); script.keepAlive(); 

注意:

不是编辑器脚本,当您单击“播放”按钮时它可以工作,但您可以使用[ExecuteInEditMode]使其在编辑器中执行。

对于我的情况,我使用Monobehaviour.Reset()方法来防止编辑器中的addcomponent。

https://docs.unity3d.com/ScriptReference/MonoBehaviour.Reset.html

当用户点击Inspector上下文菜单中的Reset按钮或第一次添加组件时,将调用Reset。 此function仅在编辑器模式下调用。 重置最常用于在检查器中提供良好的默认值。

  private void Reset() { if (this.GetType() == typeof(MyCustomClass)) { DestroyImmediate( this ); } } 

由于您要使用AddComponent添加它,因此您可能希望删除组件的MonoBehaviour部分。

考虑一下在Start中创建子组件的主要组件:

 public class TopComp: MonoBehaviour { void Start(){ this.gameObject.AddComponent(); } } 

把它变成:

 public class TopComp: MonoBehaviour { private SubComponent sub = null; void Start(){ this.sub = new SubComponent(); } } public class SubComponent{ } 

问题是你很可能想要使用所有Unity回调。 将它们添加到TopComponent并显式调用SubComponent。

 public class TopComp: MonoBehaviour { private SubComponent sub = null; void Start(){ this.sub = new SubComponent(); } void OnEnable(){ this.sub.OnEnable();} void Update(){ this.Update();} } public class SubComponent{ public void OnEnable(){} public void Update(){} }