如何为Unity3D或Spaghetti代码设计项目架构?

5
我撰写代码已经有20多年了(使用多种编程语言),在这期间,我一直使用设计模式和各种类型的架构......层次结构、责任分离、不同的类库、客户端/服务器等等。
然而,在上个周末,出于好奇和娱乐目的,我安装了Unity 3D并试用了一下。虽然我能够在Visual Studio中打开文件,但我并不理解Unity项目的默认文件结构。
为了组织我的代码,我创建了嵌套文件夹,但我一旦尝试创建一个类就有很多问题:
  • 命名空间在哪里?为什么需要自己编写?它们不应该自动根据“文件夹”结构进行考虑吗?
  • 如何创建/重用/导入不同项目的类库?
  • 如何管理NuGet包?
  • 以及我在编程中一直做的所有事情.....
我找到了一篇文章提供了一些信息,但是没有其他内容。
我想知道是否有人能够指导我关于这个主题的正确方向。
谢谢。

你在说什么?^^ 在C#中(不仅限于Unity),除非你明确指定一个不同的命名空间(参见namespace),否则类始终位于默认命名空间中。如果您使用VS,它会建议为文件夹使用相应的命名空间,但这并不是必需的。您可以将它们按程序集进行排序。对于迁移部分/库:导出和导入 - derHugo
这个问题是合法的,我知道有人问过自己这个问题。我希望StackOverflow能对它友善一些。 - Attersson
我对这个问题是否基于观点有些犹豫。正如标题所提出的“Unity3D项目架构”和如何组织代码的问题确实是纯粹基于观点的。但是关于为什么没有(自动)命名空间以及如何使用类库/nuget包的问题在我看来是有效的问题。(虽然可能更适合作为独立的问题) - Remy
1
@Remy_rm 是的,我在犹豫是基于观点还是过于宽泛。也许作为单独的问题可以,但至少问题的一半是基于观点的。 - derHugo
@Dryadwoods,你能否编辑一下这个问题,让它不那么容易引起争议? - Attersson
2个回答

4

基础知识(繁体字)

在Unity中,C#作为一种脚本语言使用,受到许多限制,并且意在按模式使用。每个Unity脚本都源自MonoBehaviour,正如您可以在文档中阅读的那样实现了特定的方法。此外,您不能使用new构造函数,而必须使用一个名为Instantiate 的工厂方法。尽管如此,只要正确包含并由任何MonoBehaviour脚本类使用,仍然可以使用其他类。

虽然这个主题存在不同的看法,但是有人认为C#脚本在Unity中结构不好[1]

命名空间和项目结构

在早期版本的Unity中,普遍共识是大型项目反映类型的文件夹结构更加整洁(例如,按类别分组的图像和类别、每个类别的脚本、预制品、纹理等),而较小的项目则更加整洁,当文件夹根据项目的语义进行命名(例如,场景或特定功能)。命名空间是完全可以的,可以在任何地方定义它们。尽管如此,已经有一个文件夹结构,并且命名空间不是100%的模式,应该在大型项目中使用以避免冲突,正如文档所示。

现代架构:实体组件系统(Entity Component System)

最近的发展引出了一种称为实体组件系统 (参见文档) 的架构。

实体组件系统(ECS)架构将身份(实体)、数据(组件)和行为(系统)分离。该架构侧重于数据。系统通过读取由实体索引的组件数据流,将数据从输入状态转换为输出状态。

这种更加现代化的开发方式改进了项目架构。不仅提高了项目的可扩展性,而且还可以重复使用代码或移植代码。即使如此,您仍然必须遵循Unity的模式并坚持接口。例如,对于Unity.Jobs,需要实现行为的接口为JobComponentSystem。最终,这都归结为坚持模式。现代项目应该坚持使用ECS。


4

命名空间在哪里?

Unity从一个模板创建“基本”C#脚本,该模板可以在以下位置找到:

  • Windows:C:\Program Files\Unity\Editor\Data\Resources\ScriptTemplates
  • Mac:/Applications/Unity/Editor/Data/Resources/ScriptTemplates
  • Mac(自5.2.1f1起):/Applications/Unity/Unity.app/Contents/Resources/ScriptTemplates

此基本脚本默认情况下不包含命名空间,但您可以通过编辑 81-C# Script-NewBehaviourScript.cs.txt 文件来添加一个。这仍将是一个静态命名空间,您需要将其硬编码到模板文件中。如果未定义命名空间,则Unity将使用全局命名空间。我找不到他们这样做的原因..但上述信息来自于此支持页面。当然,您仍然可以自行添加命名空间。

导入类库
您可以通过将它们添加到项目的/Assets/Plugins/文件夹来导入DLL。此插件文件夹是专门用于识别DLL的“特殊文件夹”。详情请参阅此手册页面:

您可以添加插件以扩展Unity的功能。插件是通常用C/C++编写的本机DLL,它们可以访问第三方代码库、系统调用和其他Unity内置功能。请始终将插件放在名为Plugins的文件夹中,以便被Unity检测到。

您只能有一个插件文件夹,并且必须将其放在项目的根目录中;直接位于Assets文件夹内。

NuGet
您可以通过Visual Studio下载和管理NuGet包。默认情况下,它将下载包到projectName/Packages/packageName。不过,Unity有时会在此处检测到这些包存在问题,因此您可能需要将它们移动到插件文件夹中。

架构
使用何种架构/文件夹结构取决于个人喜好和观点。但是Unity正在向ECS(实体组件系统)迁移。详情请参阅此处找到的文档。

实体组件系统(ECS)架构将标识(实体)、数据(组件)和行为(系统)分开。该架构专注于数据。系统通过读取由实体索引的组件数据流,将数据从输入状态转换为输出状态。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接