Unity 功能 之 创建 【Unity Package】 Manager 自己自定义管理的包的简单整理
一、简单介绍
Unity Package 是一种模块化的资源管理和分发方式,用于将游戏开发所需的代码、资源、配置文件等内容打包成一个独立的、可重用的组件。Unity Package 可以在多个项目之间共享,从而简化了项目的管理和维护。
为什么要使用 Unity Package
- 模块化管理: 将功能、资源和代码模块化,便于维护和更新。
- 复用性: 同一个包可以在多个项目中使用,避免重复劳动,提高开发效率。
- 版本控制: 可以对包进行版本管理,确保项目中使用的包是稳定和可控的。
- 团队协作: 团队成员可以共享和分发自己的包,促进协同开发。
- 依赖管理: Unity Package Manager 可以自动处理包之间的依赖关系,简化项目配置。
Unity Package 官网:Unity - Manual: Creating custom packages
二、Unity Package 的目录结构
Package 目录结构说明官网地址:Unity - Manual: Package layout
Packages/
com.example.mypackage/ # 包的根目录
package.json # 包的配置文件,包含包的元数据和依赖项
README.md # 包的说明文档,提供使用说明和其他信息
CHANGELOG.md # 包的变更日志,记录包的每个版本的更改内容
LICENSE.md # 包的许可证文件,声明包的开源许可证
Editor/ # 包含编辑器扩展脚本和资源
MyEditorScript.cs # 示例编辑器脚本
Runtime/ # 包含运行时脚本和资源
MyScript.cs # 示例运行时脚本
Tests/ # 包含测试脚本和测试资源
Editor/ # 编辑器测试脚本
MyEditorTests.cs # 示例编辑器测试脚本
Runtime/ # 运行时测试脚本
MyRuntimeTests.cs # 示例运行时测试脚本
Documentation~ # 包的文档目录,波浪号表示该目录不会被导入到项目中
index.md # 包的主文档文件
Samples~ # 包的示例目录,波浪号表示该目录不会被导入到项目中
ExampleSample/ # 示例的具体目录
SampleScene.unity # 示例场景文件
SampleScript.cs # 示例脚本文件
详细说明
1)package.json
package.json
是包的配置文件,包含包的基本信息和依赖项。例如:
{
"name": "com.example.mypackage",
"version": "1.0.0",
"displayName": "My Package",
"description": "Description of My Package",
"unity": "2020.3",
"dependencies": {
"com.unity.modules.ui": "1.0.0"
}
}
2)README.md
README.md
是包的说明文档,通常用于提供包的介绍、安装说明和基本使用方法。
3)CHANGELOG.md
CHANGELOG.md
是包的变更日志,用于记录每个版本的更新内容和变更。
4)LICENSE.md
LICENSE.md
是包的许可证文件,用于声明包的开源许可证,确保用户了解使用包的法律条件。
5)Editor/
Editor/
目录包含编辑器扩展脚本和资源,这些内容仅在 Unity 编辑器中使用。例如 MyEditorScript.cs
是一个示例编辑器脚本。
6)Runtime/
Runtime/
目录包含运行时脚本和资源,这些内容将在游戏运行时使用。例如 MyScript.cs
是一个示例运行时脚本。
7)Tests/
Tests/
目录包含测试脚本和测试资源,分为编辑器测试和运行时测试。
Editor/
包含编辑器测试脚本,例如MyEditorTests.cs
。Runtime/
包含运行时测试脚本,例如MyRuntimeTests.cs
。
8)Documentation~
Documentation~
目录用于存放包的文档文件,波浪号表示该目录不会被导入到项目中。index.md
是包的主文档文件。
10)Samples~
Samples~
目录用于存放包的示例文件,波浪号表示该目录不会被导入到项目中。示例可以帮助用户了解如何使用包中的功能。
ExampleSample/
目录包含具体的示例,例如SampleScene.unity
和SampleScript.cs
。
下面是一个 TimeLine 的 Package 目录结构
通过以上的目录结构和详细说明,可以更好地理解和组织 Unity Package,从而提高包的可维护性和复用性。在制作自己的包时,确保目录结构清晰、文件组织合理,并提供足够的文档和示例,帮助用户更好地使用包中的功能。
三、package.json 说明
package.json 说明官网地址:Unity - Manual: Package manifest
{
"name": "com.example.mypackage", // 必须。包的唯一标识符,通常使用反向域名格式。
"version": "1.0.0", // 必须。包的版本号,遵循语义化版本规范(semver)。
"displayName": "My Package", // 必须。包的显示名称,在 Unity 编辑器中显示。
"description": "Description of My Package", // 必须。包的简短描述。
"unity": "2020.3", // 必须。包兼容的最低 Unity 版本。
"dependencies": { // 可选。包的依赖项,指定其他包的名称和版本。
"com.unity.modules.ui": "1.0.0"
},
"keywords": [ // 可选。用于描述包的关键词数组,便于搜索和分类。
"utilities",
"example",
"custom"
],
"author": { // 可选。包的作者信息,可以包含 name、email 和 url。
"name": "John Doe",
"email": "john.doe@example.com",
"url": "https://example.com"
},
"license": "MIT", // 可选。包的许可证类型,通常使用 SPDX 许可证标识符。
"repository": { // 可选。包的源码存储库信息。
"type": "git",
"url": "https://github.com/example/mypackage.git"
},
"samples": [ // 可选。包含包示例的配置。
{
"displayName": "Example Sample", // 示例的显示名称。
"description": "A simple example sample.", // 示例的描述。
"path": "Samples~/ExampleSample" // 示例的路径,通常放在 Samples~ 目录中。
}
],
"changelogUrl": "https://example.com/mypackage/changelog", // 可选。包变更日志的 URL。
"documentationUrl": "https://example.com/mypackage/documentation", // 可选。包文档的 URL。
"issuesUrl": "https://example.com/mypackage/issues", // 可选。包问题追踪的 URL。
"unityRelease": "2020.3.0f1", // 可选。指定最低 Unity 修订版本。
"hideInEditor": false // 可选。指示包是否在 Unity Package Manager 中隐藏。
}
创建 Unity Package 时,包的文件结构布局非常重要,它决定了包在导入到其他项目中时的组织和使用方式。以下是一个典型的 Unity Package 的文件结构布局详细说明:
1)包根目录:
Unity Package的所有文件和文件夹都会位于一个根目录下。这个根目录的名称通常是包的名称,用小写字母表示,不包含空格。
2)package.json:
这是包的清单文件,包含有关包的元信息,如名称、版本、依赖项等。它必须位于包的根目录下。
3)Documentation文件夹(可选):
-这是包的说明文件夹Documentation,可以在其中添加Markdown或HTML文件,以便其他开发者了解如何使用包。
4)Editor文件夹(可选):
如果包包含一些只在编辑器中使用的功能,可以创建一个名为Editor的文件夹。在这里放置的脚本将只在Unity编辑器环境中执行。
5)Runtime文件夹(可选):
如果包包含在游戏运行时使用的功能,可以创建一个名为Runtime的文件夹。这里的脚本将在游戏运行时执行。
6)scripts文件夹(可选):
如果包包含一些通用的C#脚本,可以创建一个名为Scripts的文件夹,并将脚本放置在其中。这可以帮助更好地组织代码。
7)Resources文件夹(可选):
如果包包含一些资源文件,如纹理、模型、声音等,可以创建一个名为Resources的文件夹,并将资源文件放置在其中。这些资源可以通过Resources.Load函数在运行时加载。
8)Prefabs文件夹(可选):
如果包包含一些预制体,可以创建一个名为Prefabs的文件夹,并将预制体放置在其中。
9)Scenes文件夹(可选):
如果包包含一些场景文件,可以创建一个名为Scenes的文件夹,并将场景文件放置在其中。
10)Editor Default Resources文件夹(可选):
如果包包含在编辑器中使用的资源,例如图标、样式等,可以创建一个名为Editor Default Resources的文件夹,并将资源放置在其中。
11)Tests文件夹(可选):
如果为包编写了测试,可以创建一个名为Tests的文件夹,并将测试相关的文件和脚本放置在其中。Tests/Editor用于编辑器测试,Tests/Runtime用于运行时测试。
12)Examples文件夹(可选):
如果为其他开发者提供使用示例,可以创建一个名为Examples的文件夹,并在其中添加演示场景、脚本和资源。
下面是 Timeline 的 package.json 示例 :
{
"name": "com.unity.timeline",
"displayName": "Timeline",
"version": "1.6.4",
"unity": "2019.3",
"keywords": [
"unity",
"animation",
"editor",
"timeline",
"tools"
],
"description": "Use Unity Timeline to create cinematic content, game-play sequences, audio sequences, and complex particle effects.",
"dependencies": {
"com.unity.modules.director": "1.0.0",
"com.unity.modules.animation": "1.0.0",
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.particlesystem": "1.0.0"
},
"relatedPackages": {
"com.unity.timeline.tests": "1.6.4"
},
"upmCi": {
"footprint": "dcac7462836a5fa5813cc1e2c6080df1da992327"
},
"repository": {
"url": "https://github.cds.internal.unity3d.com/unity/com.unity.timeline.git",
"type": "git",
"revision": "d7e1eb6805737974459309b7d6e7db58635dd167"
},
"samples": [
{
"displayName": "Customization Samples",
"description": "This sample demonstrates how to create custom timeline tracks, clips, markers and actions.",
"path": "Samples~/Customization"
},
{
"displayName": "Gameplay Sequence Demo",
"description": "This sample demonstrates how Timeline can be used to create a small in-game moment, using built-in Timeline tracks.",
"path": "Samples~/GameplaySequenceDemo"
}
]
}
四、程序集定义
1、程序集定义说明
程序集相关官网地址:程序集定义 (Assembly Definition) 属性 - Unity 手册
程序集(Assembly)是 .NET 中的基本构件单元,它包含了代码和资源。程序集通常以
.dll
或.exe
文件的形式存在,包含了编译好的中间语言代码(CIL),元数据和资源文件。程序集在 .NET 框架中扮演着重要的角色,负责类型定义、类型解析、代码安全、代码执行和资源管理。为什么 Unity Package 需要做成程序集
在 Unity 中,使用程序集有多个优点:
模块化和组织:
- 程序集可以将代码组织成独立的模块,使代码更容易管理和维护。
- 通过将相关功能打包到单独的程序集,可以减少代码库的复杂性,提高可读性和可维护性。
编译和性能优化:
- 使用程序集可以减少编译时间。Unity 在编译时只会重新编译受影响的程序集,而不是整个项目。
- 程序集允许更细粒度的编译和优化,减少不必要的编译步骤。
代码隔离:
- 程序集提供了一种在逻辑上隔离代码的方法,避免不同模块之间的命名冲突和依赖混乱。
- 通过将代码隔离在不同的程序集内,可以更好地管理依赖关系和版本控制。
版本控制和依赖管理:
- 程序集允许版本控制和依赖管理,使得包的不同版本可以共存,并且可以明确地指定依赖项的版本。
- 这有助于确保项目中使用的程序集是稳定且兼容的版本。
安全性和权限管理:
- 程序集可以定义代码访问权限和安全策略,确保只有受信任的代码可以执行特定操作。
- 通过程序集,可以更好地控制代码的访问权限和执行环境,提高安全性。
重用和分发:
- 程序集使得代码可以方便地重用和分发。一个程序集可以在多个项目中使用,避免重复编写代码。
- 通过将功能模块打包成程序集,可以方便地共享和分发功能,提高开发效率。
在 Unity Package 中创建程序集
在 Unity Package 中创建程序集主要通过
.asmdef
文件来实现。.asmdef
文件是 Assembly Definition File,用于定义一个程序集。以下是创建和配置程序集的步骤:
创建 Assembly Definition File:
- 在 Unity 项目窗口中,右键单击需要创建程序集的目录,然后选择
Create > Assembly Definition
。- 这将在该目录下创建一个新的
.asmdef
文件。配置 Assembly Definition File:
- 选中创建的
.asmdef
文件,在检查器窗口中进行配置。- 设置程序集的名称,添加需要引用的程序集,设置编译平台等。
组织代码和资源:
- 将相关的代码和资源放入程序集对应的目录中。
- 通过
.asmdef
文件,Unity 会将这些代码和资源编译成一个独立的程序集。
2、.asmdef
文件(Assembly Definition File)配置信息说明
.asmdef
文件(Assembly Definition File)在 Unity 中用于定义和配置程序集。通过 .asmdef
文件,可以指定程序集的名称、引用、编译选项等。
{
"name": "MyCompany.MyPackage.Runtime", // 程序集名称 (必须字段)
"references": [ // 依赖的其他程序集 (可选)
"UnityEngine",
"MyCompany.MyPackage.Utilities"
],
"includePlatforms": [ // 包含的平台 (可选)
"Editor", // 例如,Editor 平台
"Standalone", // 例如,Standalone 平台
"iOS", // 例如,iOS 平台
"Android" // 例如,Android 平台
],
"excludePlatforms": [ // 排除的平台 (可选)
"WebGL", // 例如,WebGL 平台
"PS4" // 例如,PS4 平台
],
"allowUnsafeCode": true, // 是否允许不安全代码 (可选,默认为 false)
"overrideReferences": true, // 是否覆盖默认程序集引用 (可选,默认为 false)
"precompiledReferences": [ // 预编译程序集引用 (可选)
"SomePrecompiledLib.dll" // 例如,预编译的库文件
],
"autoReferenced": false, // 是否自动引用此程序集 (可选,默认为 true)
"defineConstraints": [ // 编译符号约束 (可选)
"DEBUG", // 例如,DEBUG 符号
"EXPERIMENTAL_FEATURE" // 例如,实验性功能符号
],
"versionDefines": [ // 根据包版本定义编译符号 (可选)
{
"name": "com.unity.render-pipelines.core", // 包名称
"expression": "10.0.0", // 版本表达式
"define": "UNITY_RENDER_PIPELINE_CORE_10" // 定义的符号
}
],
"noEngineReferences": true // 是否排除对 UnityEngine 和 UnityEditor 的引用 (可选,默认为 false)
}
字段说明
-
name
- 类型:
string
- 说明: 必须字段。程序集的名称。
- 示例:
"name": "Example.Utilities.Runtime"
- 类型:
-
references
- 类型:
string[]
- 说明: 可选字段。该程序集所依赖的其他程序集的名称列表。
- 示例:
"references": ["UnityEngine", "UnityEditor"]
- 类型:
-
includePlatforms
- 类型:
string[]
- 说明: 可选字段。指定程序集包含的目标平台。可以为
Editor
、Standalone
、iOS
、Android
等。若不指定,则默认包含所有平台。 - 示例:
"includePlatforms": ["Editor", "Standalone", "iOS", "Android"]
- 类型:
-
excludePlatforms
- 类型:
string[]
- 说明: 可选字段。指定程序集排除的目标平台。与
includePlatforms
互斥。 - 示例:
"excludePlatforms": []
- 类型:
-
allowUnsafeCode
- 类型:
boolean
- 说明: 可选字段。是否允许使用不安全代码(
unsafe
关键字)。 - 示例:
"allowUnsafeCode": false
- 类型:
-
overrideReferences
- 类型:
boolean
- 说明: 可选字段。是否覆盖默认的程序集引用。若设置为
true
,则必须在precompiledReferences
字段中列出所有需要的程序集。 - 示例:
"overrideReferences": false
- 类型:
-
precompiledReferences
- 类型:
string[]
- 说明: 可选字段。指定预编译程序集的名称列表,仅在
overrideReferences
为true
时有效。 - 示例:
"precompiledReferences": []
- 类型:
-
autoReferenced
- 类型:
boolean
- 说明: 可选字段。是否自动引用此程序集。如果设置为
false
,则需要手动在其他程序集的references
中添加此程序集。 - 示例:
"autoReferenced": true
- 类型:
-
defineConstraints
- 类型:
string[]
- 说明: 可选字段。指定编译时需要定义的符号(宏定义)。仅在所有符号都定义时,程序集才会编译。
- 示例:
"defineConstraints": []
- 类型:
-
versionDefines
- 类型:
object[]
- 说明: 可选字段。根据包版本定义编译符号。用于在特定包版本存在时定义符号。
- 示例:
"versionDefines": [ { "name": "SOME_PACKAGE", "expression": "2.0.0", "define": "SOME_PACKAGE_2_0_0" } ]
- 类型:
-
noEngineReferences
- 类型:
boolean
- 说明: 可选字段。是否排除对 UnityEngine 和 UnityEditor 程序集的引用。
- 示例:
"noEngineReferences": false
- 类型:
下面是 asmdef
文件(Assembly Definition File)示例:
五、简单实现一个自定义的 Unity Package
1、新建一个工程
2、创建一个测试的目录,结构如下
3、简单创建一个脚本,添加一些用来测试的函数
4、创建 MyUnityPackageTest 的 asmdef
文件(Assembly Definition File)
asmdef
文件根据需要配置,例如平台、依赖
5、可在任意位置,创建文件夹,用来构建 package 目录结构
6、添加 CHANGELOG.md、LICENSE.md、README.md 到文件夹中
根据自己的需要进行填写内容
1)CHANGELOG.md
2)LICENSE.md
3)REASDME.md
7、添加 package.json 到文件夹中
内容根据需要配置,这里简单配置,作为参考
(name : 注意全是小写,不要大写字母)
{
"name": "com.xxxx.myunitypackagetest",
"displayName": "My Unity Package Test",
"description": "My Unity Package Test",
"version": "1.0.0",
"unity": "2021.3",
"keywords": [
"unity",
"xx",
"tools"
]
}
8、添加一个 Runtime 文件夹
9、把 Unity 工程的 MyUnityPackageTest 文件夹及其所有内容拷贝
10、把拷贝的内容粘贴到 之前的 Runtime 文件夹
11、到目前为止,一个简单的 Unity Package 基本制作完成
12、新建一个Unity 工程,来测试上面制作的 Unity Package
13、菜单栏 Window - Package Manager ,弹出窗口左上角 + ,点击 Add package from disk... 选择之前制作的 Unity Package 添加进入工程
14、选择之前制作的 Unity Package 的 package.json,添加到工程
15、接下来测试一下导入的 Package 功能
16、创建测试脚本
17、把脚本挂载到场景中,运行打印如下