在Unity中模块化管理自定义功能和资源

发布时间 2023-12-01 12:36:33作者: DevBobcorn

之前在做Unity项目时,有时会遇到多个项目共用同一部分代码或资源的情况。而当被共用的部分需要更新的时候,手动复制替换非常麻烦,并且可能会有遗漏。对于这个问题,一个很好的解决办法是将可复用的文件打包为自定义包(Custom Package),使用git等版本控制工具来管理每个包的内容。

什么是Package?

在Unity中,Package可以理解为装载资源或功能的容器,可以包含如脚本、代码库、纹理、网格、动画等各种资源文件。项目中的包通过Package Manager统一管理,便捷高效。

Unity原生的许多功能集合就是以包的形式存在于项目中的,如渲染管线的核心包RP Core和管线的具体实现URP和HDRP,新版Input System,DOTS的相关功能等等,可以按需引入或移除。同样,用户也可以定义自己的Package,来实现功能或资源文件的模块化管理,这就是Custom Package。

创建一个Custom Package

Unity包本身并不能直接被打开或创建,在包的开发过程中,我们需要一个项目来作为开发的环境。在项目中创建包有两种具体做法,分别是内嵌包(Embedded Package)和本地包(Local Package),两种方法区别不是很大,这里以内嵌包为例:

第一步,给包起名字。 这里的名字是指标识符,而非在Package Manager中看到的包的标题。其命名规范与Java的包名类似,采用 顶级域名.公司或机构名.产品名 的格式书写,如 com.example.my-package,允许使用的字符仅包括小写字母,数字,连字符(-),下划线(_)和句点(.),长度尽量不超过50个字符,否则在编辑器中无法正常显示。起好名字之后,在项目的 Packages 文件夹下新建一个名称与包名相同的文件夹,并在其中创建 package.json 用来存放包的描述信息。

第二步,填写package.json。 常用的字段如下,其中仅 nameversion 字段为必填项,其余均为可选字段:

字段名 字段描述 参考示例
name (必填)包名,即第一步中的标识符 com.example.my-package
displayName 在Manager里的显示名 My Custom Package
description 描述 A util package for creating assets
version (必填)包版本 1.0.0
unity 对应Unity版本(可用unityRelease字段具体到patch) 2018.3
author 作者。可以为单字符串或json对象 Someone someone@outlook.com (https://example.com)

其它非必填字段请参阅官方文档

第三步,填充包内容。 Package内部的文件结构也有定义好的规范,官方推荐的文件结构如下:

<package-root>
  ├── package.json
  ├── README.md
  ├── CHANGELOG.md
  ├── LICENSE.md
  ├── Third Party Notices.md
  ├── Editor
  │   ├── <company-name>.<package-name>.Editor.asmdef
  │   └── EditorExample.cs
  ├── Runtime
  │   ├── <company-name>.<package-name>.asmdef
  │   └── RuntimeExample.cs
  ├── Tests
  │   ├── Editor
  │   │   ├── <company-name>.<package-name>.Editor.Tests.asmdef
  │   │   └── EditorExampleTest.cs
  │   └── Runtime
  │        ├── <company-name>.<package-name>.Tests.asmdef
  │        └── RuntimeExampleTest.cs
  ├── Samples~
  │        ├── SampleFolder
  │        └── ...
  └── Documentation~
       └── <package-name>.md

其中常用的文件和目录有:

文件或目录名 描述
package.json 包的描述信息,见第二步
README.md 与git仓库的REAME.md相同,包含了项目的介绍和基本信息等,便于使用者了解该Package
Editor 仅在Unity Editor中使用的资源,脚本,代码库等。不包含在构建出的可执行文件中
Runtime 游戏内用到的资源及代码
Tests 测试用文件,其内部也分为Runtime和Editor两类
Samples~ 示例文件及资源,注意此文件夹以"~"结尾
Documentation~ 文档资源,注意此文件夹以"~"结尾

其中,包含C#脚本的目录需要使用 Assembly Definition(.asmdef) 来定义其所属的库,一个 .asmdef 可以管辖与其同级的文件及与其同级的文件夹下的所有文件,详见文档。另外,对于以"~"结尾的目录,Unity不会为其与其内容生成 .meta 文件。其他目录下的文件则与在 Assets 目录下的文件相同,使用 .meta 文件来辅助追踪和标识。

使用git管理Custom Package

包的内容完成并测试通过后,进入 package.json 所在的目录并打开终端,按照常规流程建立git仓库,添加并提交更改,然后push到八爪猫上的远程仓库即可。引入和更新的时候也很方便,在Package Manager界面里点左上角的加号,选择 Add from git url...,输入八爪猫的仓库地址即可。不过这里要注意地址不是仓库八爪猫主页的地址,而是带有 .git 后缀的git仓库地址,不然会提示找不到仓库。

此外,与Unity内置包的版本控制不同,从git添加的Package会有一个hash值来标识其版本,而非仅通过 package.json 中定义的版本号来判断。也就是说,如果你更新了包的内容但没有改版本号,使用这个包的项目通过Package Manager也是能够发现这个差异并且更新包中的内容的。