Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.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# 使用嵌套类作为Unity3D组件_C#_Unity3d_Unity5_Inner Classes_Unity Components - Fatal编程技术网

C# 使用嵌套类作为Unity3D组件

C# 使用嵌套类作为Unity3D组件,c#,unity3d,unity5,inner-classes,unity-components,C#,Unity3d,Unity5,Inner Classes,Unity Components,我使用的是Unity 5.4.2f2 Personal,我编写了一个类似于以下内容的C#脚本: using UnityEngine; using System; public class Outer : MonoBehaviour { // Some public outer fields public class Inner : MonoBehaviour { // Some public inner fields } } 我希望能够将外部和内

我使用的是Unity 5.4.2f2 Personal,我编写了一个类似于以下内容的C#脚本:

using UnityEngine;
using System;

public class Outer : MonoBehaviour {

    // Some public outer fields

    public class Inner : MonoBehaviour {
        // Some public inner fields
    }

}

我希望能够将
外部
内部
附加到场景中的游戏对象。不幸的是,
internal
在Unity Inspector中没有显示为可用脚本,即使我向其中添加了
[Serializable]
。我知道,如果我试图使嵌套类对外可见,很多人可能会说我的设置有问题,但出于这个问题的考虑,我只想知道这是否可以实现。也就是说,有没有办法使嵌套类可用作Unity组件?

没有,没有办法将嵌套类用作Unity组件。要将MonoBehavior类用作unity组件,类名必须等于脚本的文件名,因此不能使用嵌套类

如果在不重命名脚本文件的情况下,将外部类重命名为任何其他名称,则将无法使用新的外部类

[编辑]

我找到了那个。正如我所说:
“类名和文件名必须相同,才能将脚本组件附加到游戏对象上。”

我不相信前面的答案是正确的

您应该能够通过使用[MenuItem]attr创建带有静态方法的编辑器脚本来添加嵌套的组件,以创建和绑定MonoBehavior


这在Unity 5及更高版本中有效。

您不能通过Unity标准菜单添加它。 但您可以通过脚本添加它。
AddComponent()

自从我问了这个问题后,我学到了很多,所以我想我会再补充一些信息。在技术上仍然是正确的,因此我将保留它作为可接受的答案

Unity如何编译脚本 Unity使用内置版本的Mono编译器(跨平台C#编译器)编译项目中的所有脚本。它为每个脚本文件(在关联的
.meta
文件中)分配一个唯一的GUID,就像它为其他所有资源分配一样。这带来了一些很好的可用性改进:可以重命名类而不破坏现有脚本引用,因为GUID不会更改,脚本可以与其他相关资产一起分组到文件夹中(例如,所有“士兵”脚本/声音/纹理可以分组在一起)

Unity的脚本命名限制 这种可用性的缺点是Unity强制了一些命名限制:

  • 每个文件只有一个与文件同名的类,因为否则Unity将不知道在组件脚本引用中使用哪个GUID
  • 没有嵌套类
  • 在名为
    mybehavior.cs
  • 可能没有
    partial
    类(尚未测试)
但是,这些限制仅适用于从
monobhavior
(或者可能从
UnityEngine.Object
?)派生的公共类。您可以在一个文件中拥有任意数量的其他私有
monobhavior
s或您想要的,因为Unity永远不会序列化它们,所以它们不需要自己的GUID。标有
[Serializable]
的公共POCO可能具有与Public
monobhavior
相同的命名限制。我还没有对此进行测试,所以我不确定。为什么我没有测试这个?嗯

使用托管插件避免这些限制 如果你和我一样,来自纯.NET背景,那么任何关于哪些类可以在哪些文件中定义的限制都可能让你恼火。在这种情况下,您可以将脚本存储在Unity项目之外(我使用与Unity项目相同的repo中的另一个文件夹),并使用诸如Visual Studio或JetBrains Rider之类的IDE手动构建它们。生成的程序集(.dll和.pdb文件)随后可以复制到Unity项目中(理想情况下是通过一些自动生成后事件)。然后你可以:

  • 根据需要为每个文件定义尽可能多的类
  • 使用您想要的任何命名约定
  • 使用嵌套类和
    partial
    类,无论您想要什么,与纯.NET相同
  • 为您的POCO编写不依赖Unity或Unity测试框架的单元测试(这有一个让您并行运行单元测试的好处;Unity一次只能运行一个测试)
  • 您甚至可以使用任何您想要的C#版本(尽管有些语言功能需要运行时功能,但Unity版本的Mono中没有这些功能)。Unity 5.x中的C#版本限制实际上是促使我首先选择此选项的原因
不过,这显然是一种更低级的脚本编写方法,需要更多的C#、CLR、MSBuild等知识。然而,如果你不怕弄脏你的手,那么Ashley Davis有一个关于设置Visual Studio来生成托管插件的方法,以及这种方法的优缺点。您还可以在源代码项目中使用优秀的工具对Unity程序集进行跨平台和经得起未来考验的引用


希望这能澄清问题,再次感谢前面的回答/评论

谢谢你的回答!我发现一个关于Unity答案的问题似乎与您的意见一致(下面的链接),但我在文档中找不到任何关于此规则的正式提及。你有没有偶然的链接?当我看到你的问题时,我搜索了unity文档,但我也找不到这些信息。我只因为以前的经历才知道。尝试重命名外部类并将脚本拖动到某个游戏对象,您将看到错误消息awesome,谢谢链接。非常感谢你的帮助!说一些“应该”的话纯粹是推测,如果没有适当的例子或只是在教学中投入更多的精力,就不是建设性的回答。