Unity 自製 Package
分類
說明
不知道大家是否有用過 Package Manager 安裝 Package(套件),只需找到要使用的套件,並且安裝就能使用,可說是相當方便,本篇將分享自製 Package 快速上手篇,讓大家可以輕鬆地建立套件。
在專案底下建立套件
首先我們需要先定義公司名稱和套件名稱。
- 公司名稱: Enjoy
- 套件名稱: EnjoyPackage
接著我們在 {Project}/Packages/ 目錄下新增資料夾,名稱為套件名稱,這裡為 EnjoyPackage。
套件佈局
在建立套件之前,我們需要先了解套件的佈局,佈局意思是每個檔案或資料夾的用途,Unity 已經幫我們定義好一些了佈局了。
<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~
  │        ├── SampleFolder1
  │        ├── SampleFolder2
  │        └── ...
  └── Documentation~
       └── <package-name>.md
<package-root> 就是套件的根目錄。
此範例我會使用 Runtime 資料夾,Runtime 資料夾主要是用來存放 Unity 運行時會用到的腳本。
詳情請參考 Package layout
package.json
首先我們需要先定義 package.json,在 EnjoyPackage 資料夾底下新增 package.json。
package.json
{
  "author": {
    "name": "EnjoySoftware",
    "email": "veryenjoysoftware@gmail.com",
    "url": "https://veryenjoy.tw"
  },
  "dependencies": {
    "com.unity.textmeshpro": "*"
  },
  "description": "Enjoy package",
  "displayName": "EnjoyPackage",
  "keywords": [
    "Enjoy",
    "Package"
  ],
  "name": "com.enjoy.enjoy_package",
  "samples": [
    {
      "displayName": "Sample",
      "description": "Demo sample",
      "path": "Samples~/Sample1"
    }
  ],
  "unity": "2023.1",
  "version": "0.0.1"
}
目前我有使用的屬性如上,至少要有 name, version。
- author: 作者資訊。
- dependencies: 此套件所依賴的套件,鍵是套件名稱,值是套件版本號。
- description: 在 Package Manager 顯示的描述。
- displayName: 在 Package Manager 顯示的名稱。
- keywords: 在 Package Manager 搜尋關鍵字。
- name: 可當作是套件 id,命名格式建議 <domain-name-extension>.<company-name>.<package-name>,注意不要有大寫。
- samples: 給使用者參考的樣本。
- unity: unity 要求版本。
- version: 套件版本,以三個字數格式,越往左邊的數字代表越大的更動,越難相容之前的版本。
詳情請參考 Package manifest
語意化版本
dependencies 和 version 使用的是語意化版本,這是一個定義版本的規範,相當實用。
你可以看到範例中的 dependencies 我使用 * 指定版本,我把它當作 wildcard 通配符號來用,例如: 1.0.* 就是 1.0.1、1.0.9 都可以,但其實文件上並沒有找到可以用 * 的記載,所以最好還是指定完整版本比較好。
新增運行時腳本
在這裡新增腳本用來示範套件是否有正常運行。
新增 Runtime/Example.cs 腳本
Example.cs
using UnityEngine;
namespace Enjoy
{
    public class Example : MonoBehaviour
    {
        private void Start()
        {
            Debug.Log("Package working!");
        }
    }
}
我有使用 namespace,使用命名空間是為了避免檔案衝突,命名空間名稱沒有規範,我使用的命名空件是 Package.Function,例如: Enjoy.DesignPattern 命名空間用來存放跟設計模式有關的腳本。
此腳本很簡單,當遊戲物件添加此腳本組建就會在控制台輸出 Package working!
 
 
新增 Assembly Definition
你可以看到套件佈局中 Runtime 資料夾底下有一個 <company-name>.<package-name>.asmdef 檔案,這個檔案跟編譯有關,實際上我沒有很仔細地去了解,但記得要加上這個檔案就是了。
以此範例來說,在 Runtime 資料夾底下新增 enjoy.enjoy_package.asmdef。
在 Project 標籤頁中選擇套件的 Runtime 資料夾,在瀏覽檔案的空白處按右鍵 > Create > Assembly Definition。
點擊 .asmdef 檔在 Inspector 會看到一些配置選項,以目前的範例來說保留預設就好。
詳情請參考 Assembly definitions
Samples
關於套件的樣本(Sample),文件上說可以放各種資產(Assets),但實際上我發現他還是存在 .meta 不能存在裡面的問題,你會看到 Samples~ 資料夾名稱結尾有波浪號,這是用來讓 Unity 編輯器忽略含有波浪號的資料夾,因此就不會自動產生 .meta 檔,因為如果 Samples~ 裡面含有 .meta 檔,在匯入樣本到專案裡面時,就會發生套件的樣本和匯入到專案的樣本有相同的 .meta 檔,若有相同的 .meta 檔就會發生 .meta 的 guid 重複的問題。
假設不能存放 .meta 到樣本裡面,這就代表著有些配置沒辦法被存下來,像是 png, prefab 等等,所以存入樣本的資料必須是不依賴 .meta 檔案才行,所以我會另外建立一個資料夾 SampleAssets 用來存放需依賴 .meta 的資料,然後記得如果有使用腳本就要在 SampleAssets 新增 Assembly Definition,以此範例就是 enjoy.enjoy_package.SampleAssets.asmdef。
樣本的場景檔案要放在 Samples~ 裡面,因為 SampleAssets 沒辦法開啟場景檔案,他會跳出 SampleAssets 是唯讀狀態,但好消息是,場景檔案可以使用 SampleAssets 裡面的資料,在匯入樣本場景到專案裡面時一樣會參考套件裡面的 SampleAssets 裡面的資料。
說明文件
最主要的是 README.md、CHANGELOG.md、LICENSE.md,這些在一般專案多少都會看到,依照自己的需求撰寫即可。
- README.md: 套件說明,想說的話都可以放這裡。
- CHANGELOG.md: 更新日誌。
- LICENSE.md: 版權聲明。
README.md、LICENSE.md 這兩份文件在 GitHub 上建立一個新的倉庫時,會提供生成這兩個檔案的選項,你可以參考或直接拿來用。
更新日誌有固定格式,不過不會太困難,請參考下方更新日誌。
更新日誌
更新日誌(Changelog)是說明專案在開發過程中,版本之間的差異紀錄,由開發人員由新而舊撰寫。
此更新日誌有固定格式,按照官方文件的風格撰寫,你可以將此風格用在其他地方。
更詳細的說明請參考官方網站 keep a changelog。
改動類型
主要有這些類型,使用方式直接參考下方範例。
- Added:當增加了新功能。
- Changed:當更動了既有的功能。
- Deprecated:當功能將在近期被移除。
- Fixed:當修復了某些錯誤。
- Removed:當移除了現有的功能。
- Security:當增進了安全性漏洞。
- Unreleased: 即將發佈的更新內容。
範例
CHANGELOG.md
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [1.1.1] - 2023-03-05
### Added
- Arabic translation (#444).
- v1.1 French translation.
- v1.1 Dutch translation (#371).
- v1.1 Russian translation (#410).
- v1.1 Japanese translation (#363).
- v1.1 Norwegian Bokmål translation (#383).
- v1.1 "Inconsistent Changes" Turkish translation (#347).
- Default to most recent versions available for each languages
- Display count of available translations (26 to date!)
- Centralize all links into `/data/links.json` so they can be updated easily
### Fixed
- Improve French translation (#377).
- Improve id-ID translation (#416).
- Improve Persian translation (#457).
- Improve Russian translation (#408).
- Improve Swedish title (#419).
- Improve zh-CN translation (#359).
- Improve French translation (#357).
- Improve zh-TW translation (#360, #355).
- Improve Spanish (es-ES) transltion (#362).
- Foldout menu in Dutch translation (#371).
- Missing periods at the end of each change (#451).
- Fix missing logo in 1.1 pages
- Display notice when translation isn't for most recent version
- Various broken links, page versions, and indentations.
### Changed
- Upgrade dependencies: Ruby 3.2.1, Middleman, etc.
### Removed
- Unused normalize.css file
- Identical links assigned in each translation file
- Duplicate index file for the english version
上傳 GitHub
當以上步驟都完成之後,可以先上傳到 GitHub 上,之後在其他遊戲專案就能夠開啟 Package Manager 使用 git URL 安裝,基本上只需將整包套件丟上去就好。
或者可以新增 Repository,再將套件的檔案上傳上去。
- Repository name: 套件名稱
- 選擇公開還是私有
- 選擇是否要新增 README
- .gitignore 選擇 Unity
- 選擇版權聲明

要記得讓 Unity 生成 meta 檔,將套件放到 Unity 專案 Packages 底下,然後打開 Unity 專案就會自動新增 meta 檔。
如果 Repository 為私有的話,可能會需要輸入帳號密碼之類的,或者是需要分配權限等等,因為我是個人使用,所以我就沒有太深入了解這個部分。
更新套件
目前我還沒有找到一個辦法可以直接更新安裝好的套件,所以如果要維護套件,我建議開一個專門用來維護套件的 Unity 專案,然後在 Packages 資料夾底下使用 git clone 的方式將套件下載下來,Visual Studio Code 開啟 Unity 專案時一樣可以解析 Unity 的程式碼,修改套件後,可以直接推上 git 遠端。
我的套件檔案結構
最後附上我的套件檔案結構給大家參考。
.
├── LICENSE.md
├── LICENSE.md.meta
├── README.md
├── README.md.meta
├── Runtime
│   ├── Example.cs
│   ├── Example.cs.meta
│   ├── enjoy.enjoy_package.asmdef
│   └── enjoy.enjoy_package.asmdef.meta
├── Runtime.meta
├── SampleAssets
│   ├── Sample1
│   │   ├── Prefabs
│   │   │   ├── Sample1.prefab
│   │   │   └── Sample1.prefab.meta
│   │   ├── Prefabs.meta
│   │   ├── Scripts
│   │   │   ├── Sample1.cs
│   │   │   └── Sample1.cs.meta
│   │   └── Scripts.meta
│   ├── Sample1.meta
│   ├── enjoy.enjoy_package.SampleAssets.asmdef
│   └── enjoy.enjoy_package.SampleAssets.asmdef.meta
├── SampleAssets.meta
├── Samples~
│   └── Sample1
│       └── Scenes
│           └── Sample1.unity
├── package.json
└── package.json.meta
參考
一杯咖啡的力量,勝過千言萬語的感謝。
支持我一杯咖啡,讓我繼續創作優質內容,與您分享更多知識與樂趣!