以下の内容はhttps://www.hanachiru-blog.com/entry/2025/02/27/120000より取得しました。


【Unity】.unitypackageをUnityを利用せずに展開・圧縮できるPowerShellのモジュールを作った話 (CI/CDでも利用可)

はじめに

先日.unitypackageをUnityを利用せずに展開・圧縮できるPowerShellのモジュールを作成しました。

今回は背景、概要、使い方、開発秘話あたりを書こうと思います。

背景

.unitypackageはUnityプロジェクトのファイルやデータ等々を圧縮したファイルフォーマットです。中にメタデータも含まれているので、諸々の設定も維持されます。

アセットパッケージは、Unity プロジェクトのファイルやデータ、またはプロジェクトの要素を集めたもので、Unity が圧縮して、拡張子 .unitypackage の 1 つのファイルに格納します。アセットパッケージは、zip ファイルと同様に、解凍しても元のディレクトリ構造が維持され、アセットに関するメタデータ (インポート設定や他のアセットへのリンクなど) も維持されます。

アセットパッケージ - Unity マニュアル

基本的に.unitypackageの展開・圧縮にはUnityが必要になります。UnityEditorのGUI上で実行したり、バッチモードでAssetDatabaseを使うとかですね。

docs.unity3d.com
docs.unity3d.com

ただ.unitypackageの中にどんなものが入っている調べたい場面や、CI/CDで.unitypackageを生成したい場面に、わざわざUnityを立ち上げるのは非常にめんどくさいです。Unityの立ち上げ時間もそうですし、CI/CDではまずUnityを用意するの自体が面倒です。

パッケージ紹介

前述の背景から、以下の要件を満たすようなものが欲しくなりました。

  • Macのターミナルなどローカル環境でも簡単に.unitypackageの中身を知りたい
  • CI/CDでも気軽に.unitypackageを生成したい

それらを実現するためにUnityPackageArchiverというPowerShellのモジュールを作成しました。

概要

利用するにはPowerShellが利用できる前提で、以下のコマンドでモジュールをインストールすれば使えるようになります。

使い方

インストール方法

PowerShell上で以下のコマンドを実行してモジュールをインストールします。

$ Install-Module -Name UnityPackageArchiver -Force

展開方法

$ Expand-UnityPackage -UnityPackagePath "./path/to/target.unitypackage" -OutputDir "./output/directory"

一応PowerShellの決まりとして、接頭辞がある程度決められています。ExpandCompressはそれに従って命名されていたりします。
PowerShell コマンドに承認されている動詞 - PowerShell | Microsoft Learn

圧縮方法

$ Compress-UnityPackage -OutputFilePath "./path/to/output.unitypackage" -TargetFiles "./path/to/Assets/MyAsset.prefab", "./path/to/Assets/MyScript.cs"

PowerShellでパラメーターで配列を受け取るときは空白ではなく,で区切る必要があるので注意です。

またAssets以下の.cs.prefabを選択すれば、自動で.metaも対象に入ります。逆に.metaだけを指定しても無視されるので注意してください。

あとpreview.pngというアセットストアで公開する際にプレビュー画像としてサイト上に表示される画像は対応していません。アセットストアで公開する場合以外には関係ないはずなので、実用上は特に問題ない認識です。

CI/CDでの利用

- name: Use Expand-UnityPackage
  uses: hanachiru/UnityPackageArchiver/Expand-UnityPackage@main
  with:
    unity-package-path: "./Tests/Data/Expand/Input/sample.unitypackage"
    output-dir: "./Tests/Data/Expand/Output"

- name: Use Compress-UnityPackage
  uses: hanachiru/UnityPackageArchiver/Compress-UnityPackage@main
  with:
    output-file-path: "./Tests/Data/Compress/Output/Sample.unitypackage"
    target-files: "./Tests/Data/Compress/Input/Assets/Prefabs/GameObject.prefab, ./Tests/Data/Compress/Input/Assets/Sprites/note.png"

Unityを用意する必要はありません。

target-filesが一つ一つのファイルを,で区切ってください。

その他感想

Why Powershell

今回実装するにあたって、以下の選択肢をまず考えました。

  • bashで書く
  • PowerShellで書く
  • dotnet toolを作成する

まずbashに関してですが、同じコマンドでも環境によって方言があったり、Windowsで動かそうとするとWSL等が必要だったりと少し辛いです。また個人的に複雑な処理をさせようとするとかなり職人芸チックになるので、できれば書きたくないです。

対してPowerShellはWindows、macOS、Linuxでも動きます(Powershell6から)し、記法も結構直感的です。またC#使いであれば、そもそもランタイムが同じなのでSystem名前空間の関数とか普通に呼び出せますし、学習もかなり容易な分類じゃないかと個人的に思ってます。型もあります。
learn.microsoft.com

.NETでツールを作成して配布するという手法も捨てがたくはあります。最近はCySharpのProcessX + ConsoleAppFrameworkという構成が個人的に好きなのですが、利用するのに一定.NETの知識が求められてしまうのが少しマイナスかなという気もしてます。(普段から.NETに慣れている人であればかなり便利ではあるのですが...)

GitHub Actionsにもshell: pwshとか書くだけでPowerShellを記述できますし、その観点でもCI/CDでは多少PowerShellが楽かなという印象です。

PowerShell or dotnet toolに関してはまあどちらでも良いですが、PowerShellの自作モジュール作成をしたことがなかったので興味でそちらを選んでみたというのが一番大きかったといえば大きかったです。

PowerShellでテストを書くということ

今回はモジュール作成をする上で簡単なテストを活用していましたが、PowerShellのテストは結構分かりやすくて良かったです。
github.com

# 単体テストの例
BeforeAll {
    Import-Module "${PSScriptRoot}/../../UnityPackageArchiver" -Force

    if (Test-Path -Path "${PSScriptRoot}/../Data/Compress/Output") {
        Remove-Item -Path "${PSScriptRoot}/../Data/Compress/Output" -Recurse -Force
    }
    New-Item -ItemType Directory -Path "${PSScriptRoot}/../Data/Compress/Output" -Force
}

Describe 'Compress-UnityPackage' {
    Context 'Normal Scenario' {
        It 'Exclude files with .meta extension' {
            Compress-UnityPackage `
                -OutputFilePath "${PSScriptRoot}/../Data/Compress/Output/sample.unitypackage" `
                -TargetFiles "${PSScriptRoot}/../Data/Compress/Input/Assets/Prefabs/GameObject.prefab", `
                "${PSScriptRoot}/../Data/Compress/Input/Assets/Prefabs/GameObject.prefab.meta"
            Test-Path -Path "${PSScriptRoot}/../Data/Compress/Output/sample.unitypackage" | Should -Be $true 
        }
    }

これはPesterというテストフレームワークを活用して記述しています。一番有名なテストフレームワークみたいです。

pester.dev

まだ全然使いこなせていないですが、かなり使いやすく今のところは好印象ですね。

PowerShell Galleryについて

.NETのnuget.orgのように、PowreShellにもPowerShell GalleryというPowerShellのコードを共有・取得できるレポジトリがあります。
www.powershellgallery.com

例えばUnityで検索していただくと分かるかと思いますが、まだモジュール自体もNuGetと比較してかなり少ない印象を受けます。

悪く捉えればまだ発展途上ですが、よく捉えれば自分でモジュールをじゃんじゃん作れます。nuget.orgを見たりしてみると、まあ猛者たちがライブラリを作成してるのでなかなか初心者が入る隙間は少ないです。




以上の内容はhttps://www.hanachiru-blog.com/entry/2025/02/27/120000より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14