防止在编辑器中添加组件

时间:2017-09-27 12:26:25

标签: c# unity3d mono

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

原因是我使用AddComponent<T>()手动附加了此组件。所以这是一个更方便的问题,我只是不希望用户认为他必须手动添加我的组件才能让我的插件工作。 (如果他做了,那不会造成任何麻烦。再次,这只是方便)

精密工业

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

我还试图简单地将我的类放在内部,因为它实际上就是这样,程序集应该是唯一可以访问此组件的程序集。但是,我害怕从MonoBehaviour继承,即使使用内部类也可以在编辑器中使用该组件......

HideInInspector属性似乎不适用于某个类。

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

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

5 个答案:

答案 0 :(得分:3)

  

因此,我不希望我的组件出现在用户可见的任何位置。

下面的代码段应该隐藏编辑器(Inspector and Hierarchy)中的脚本。

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

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

只要您的脚本继承自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<MoveTowards>();

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

enter image description here

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

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

注意:

这是一个编辑器脚本,当你点击&#34; Play&#34;按钮,但您可以使用[ExecuteInEditMode]使其在编辑器中执行。

答案 1 :(得分:2)

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

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

您可以轻松地添加课程:

gameObject.AddComponent<NotAMonoBehaviour.MyMonoBehaviour>()

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

答案 2 :(得分:1)

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

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

  

当用户单击检查器中的“重置”按钮时,将调用“重置”。   上下文菜单或首次添加组件时。这个   函数仅在编辑器模式下调用。重置最常用于   在检查器中提供良好的默认值。

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

答案 3 :(得分:0)

由于您使用AddComponent添加它,可能您想要删除组件的MonoBehavi部分。

考虑一下在Start:

中创建子组件的主要组件
public class TopComp: MonoBehaviour
{
    void Start(){
        this.gameObject.AddComponent<SubComponent>();
    }
}

把它变成:

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(){}
}

答案 4 :(得分:0)

我有一个简单的解决方案,但我不确定100%。它为您的Component命名与CS文件名不同。