Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 防止在编辑器中添加组件_C#_Unity3d_Mono - Fatal编程技术网

C# 防止在编辑器中添加组件

C# 防止在编辑器中添加组件,c#,unity3d,mono,C#,Unity3d,Mono,我正在寻找一种方法来禁用在Unity编辑器中附加MonoBehavior组件的可能性。 因此,我不希望我的组件出现在用户可见的任何地方 原因是我使用AddComponent()从脚本手动附加此组件。所以这是一个更方便的问题,我只是不想让用户认为他必须手动添加我的组件才能让我的插件工作。(如果他真的这么做了,那也不会造成任何麻烦。再说一次,这只是方便而已) 精密度 我正在编写一个库(dll插件),所以我不能使用与我的组件不同的命名文件的技巧,但这正是我想要的效果 我还试图简单地将我的类作为内部类,

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

原因是我使用
AddComponent()
从脚本手动附加此组件。所以这是一个更方便的问题,我只是不想让用户认为他必须手动添加我的组件才能让我的插件工作。(如果他真的这么做了,那也不会造成任何麻烦。再说一次,这只是方便而已)

精密度 我正在编写一个库(dll插件),所以我不能使用与我的组件不同的命名文件的技巧,但这正是我想要的效果

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

hideInInstitct
属性在类上似乎不起作用

我正在用一个静态方法调用
AddComponent
,因此我没有任何其他行为可依赖

如果我们能找到答案,这将是一个相当大的挑战。
有什么想法吗?非常感谢您

因为您是使用AddComponent添加它的,也许您想删除组件的MonoBehavior部分

假设您拥有在“开始”中创建子组件的主组件:

public class TopComp: MonoBehaviour
{
    void Start(){
        this.gameObject.AddComponent<SubComponent>();
    }
}
问题是您很可能希望使用所有Unity回调。将它们添加到TopComponent并显式调用子组件

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(){}
}
因此,我不希望我的组件出现在用户可见的任何地方

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

我正在寻找一种方法来禁用连接我的 Unity编辑器中的MonoBehavior组件

只要您的脚本继承自
monobhavior
,您就无法阻止人们将其附加到游戏对象上

不过,你可以这样做,当他们将其附加到游戏对象时,你抛出一个错误,然后销毁该组件。将变量设置为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>();
注意:


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

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

class NotAMonoBehaviour {
  class MyMonoBehaviour : MonoBehaviour {
    //etc.
  }
}
您可以很容易地添加该类:

gameObject.AddComponent<NotAMonoBehaviour.MyMonoBehaviour>()
gameObject.AddComponent()

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

对于我的情况,我使用monobhavior.Reset()方法来防止在编辑器中添加组件

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


我有一个简单的解决方案,但我不是100%确定。它的命名方式与cs文件名不同。

它是运行时添加组件还是编辑器脚本?在运行时执行此操作可能会对用户造成性能问题-如果不会导致任何问题,则可能会让用户自行决定是否要手动添加它?是的,在运行时执行,但在第一个场景加载时执行一次。公平地说,我正在为一项服务编写一个库,所以如果他下载我的库,那已经是因为他想让我的行为出现在那里了……我明白了!不幸的是,我对你的问题没有答案。你不能用
[RequireComponent(typeof(YourScript))]
代替AddComponent?不太可能。我的组件是从一个实例中实例化的,所以我没有任何其他的MonoBehavior来保存,这几乎是我所需要的。我正在用这个属性在函数中实例化我的组件:所以我没有其他游戏对象可以用作持有者…这是经过深思熟虑的,非常感谢!它实现了我试图实现的目标:告诉用户他们不必自己添加它。如果这是最好的解决方案,我会在今天结束前将其标记为解决方案。再次感谢!我不敢相信这真的奏效了!伙计,这真是太棒了,太谢谢你了,一点也不棒!我会试一试的。谢谢使用
monobhavior.Reset()
的好主意。我以前的解决方案涉及
monobhavior.Awake()
ExecuteInEditMode
。Unity要求组件名与文件名相同。
GameObject testObj = new GameObject("Test");
MoveTowards script = testObj.AddComponent<MoveTowards>();
script.keepAlive();
class NotAMonoBehaviour {
  class MyMonoBehaviour : MonoBehaviour {
    //etc.
  }
}
gameObject.AddComponent<NotAMonoBehaviour.MyMonoBehaviour>()
    private void Reset()
    {
        if (this.GetType() == typeof(MyCustomClass))
        {
            DestroyImmediate( this );
        }
    }