大量のアセットを機械的に処理したい!ということで、Pythonに手を出すことにしました
この記事は
- UnrealEnginePythonではなく、公式でサポートされたPythonPluginを扱います
- UE4.22で確認します
- python触るのは今回がはじめて
実際に作っていくとあれこれ欲しくなるので、Plugin拡張&ビルドしてライブラリを足したりしてます- 思ったより公開されてました、なので今回は拡張なしで出来る範囲で紹介します
- ただ必要な関数を探すのが大変なので、余裕がない場合は自作するのもいいかも
開発環境の構築
Python を使用したエディタのスクリプティング
まずは公式ドキュメントを読むことをお勧めします
なかなか大事なことがさらりと短く書いてあるので、見落としがないように(自戒)
「Python を使用するようプロジェクトを設定」の通りに、PythonScriptPluginを有効化
UE4のコンソールでPythonが実行できるようになりました
Pythonインストール
PythonScriptPluginに合わせて2.7.14をインストールします
UE4エディタでの実行であれば内包されているものを使えばよいのですが、後述するソースエディタでどちらにせよ必要になります
Python Release Python 2.7.14 | Python.org
Python公式からダウンロードしてインストール
ちょっと調べると仮想環境作ったほうがいいとか書かれてますが、UE4でしか使わないのでこれでいいんですzz
エンジンのビルドができるのであれば、環境変数「UE_PYTHON_DIR」を書き換えることで別のバージョンを指定することも可能!とのことですが、そこまで不自由を感じなかったので保留
ソースコードエディタ設定
いつも愛用しているVSCodeを使います
Linterやオートフォーマットが結構良さげでした
Python拡張機能
拡張機能から検索してインストールします
インストール後、Pythonがないと怒られる図
Pythonをインストール後、右下に出るサジェスト通りに進めてLinter,Formatterをインストールします
Pythonのエディタ設定
はじめに — pep8-ja 1.0 ドキュメント
Pythonで学ぶ 基礎からのプログラミング入門(36) Pythonのコーディング規約「PEP8」
コード規約通りに書かないとダメ(そもそも動かない)な点が多いので、エディタである程度固めておいた方がよいです
VSCodeは言語毎の設定ができるようになっています
- Ctrl+Shift+Pを押す
- [Preferences: Configure Language Specific Settings...]を検索して実行
- [言語の選択]と出るので、Pythonを検索して実行
- settings.jsonが開くので、以下を設定
{
"[python]": {
"editor.formatOnSave": true,
"editor.formatOnPaste": true,
"editor.insertSpaces": true,
"editor.tabSize": 4,
}
}
Pythonでプログラミング
の前に、APIリファレンスにざっと目を通しておきます
EditorScriptingUtilitiesのModule内にあるものが、PythonのHelper的なクラスで実装してあると思うので、こちらもチェック
- unreal.EditorAssetLibrary -> Assetへのアクセス
- unreal.EditorFilterLibrary -> 配列のフィルタリング
- unreal.EditorLevelLibrary -> レベルを開いた状態での操作ヘルパ
- unreal.EditorSkeletalMeshLibrary -> SkeletalMeshのプロパティ操作
- unreal.EditorStaticMeshLibrary -> StaticMeshのプロパティ操作
公式サンプルは申し訳程度にしか置いていないので、こちらを参考にしました
サンプル
今回書いたソースコードはこちら
Pluginsに入れて使います
未参照(使用されてない)のアセットを一覧で出力する
[Asset/ReportUnusedAssets]
(https://github.com/koorinonaka/UE4PythonScriptSample/blob/master/Content/Python/asset/report_unused_assets.py)
(画像はさらにクラス名でフィルタ)
サンプルを参考に実装したものの、unreal.EditorAssetLibrary が実はMapの参照に対応してないじゃん・・・
と、諦めかけたその時、ありました!
unreal.AssetRegistryHelpers と unreal.AssetRegistry 、こっちのほうが遥かに充実してない?
ファイル名の重複を検出
Asset/ReportDuplicatedAssetNames
コピーしたアセットの消し忘れのために、unusedと組み合わせるとなお良し
アセット検索で同名が表示されたりするので、ユニークな命名にするようにしましょう
ファイル名のUnicodeを検出
Asset/ReportUnicodedAssetNames
気を付けていても_とか全角アルファベットつけちゃうことあるよね
if isinstance(package_name, unicode):
unicodeとの比較で判定します
中身が空のディレクトリを削除
Asset/DeleteUnusedLocalDirectories
Perforceでは他人が消したディレクトリを消してくれないので(実は設定で出来るらしいと、聞いたけど)
init_unreal.pyとかに設定するとよいかもしれない
コンテンツブラウザ上だと中身が空でも、見えないだけで実際はファイルが存在している場合(Pythonとか)はディレクトリ削除に失敗するので、FileManagerからファイルを取得する関数を作成するほうがよい
FPackageName::FindPackagesInDirectoryとかを使うのがよさげ?
テクスチャのプロパティを変更
Texture/ValidateProperties
サンプルではUIテクスチャの設定として、MipGenSettingsとTextureGroupを修正している
テクスチャ圧縮可否のサイズ判定
Texture/ReportAssets
圧縮テクスチャ メモリ要件
DXT は、パレットカラーおよび補間カラーを持つ 4x4 ブロックにピクセルをパッキングすることに基づいた不可逆圧縮を使用します
テクスチャを圧縮するためには4の累乗である必要があるので、不適切なサイズのアセットを検出しています
コマンドラインからの起動
深夜に自動でスクリプトを実行したいじゃないですか?
コマンドラインの項に沿って起動します
-
エディタを通常通り起動する場合(たぶんMapとかを直接開いて操作するとかはこっち)
ex."[EnginePath]\Engine\Binaries\Win64\UE4Editor-Cmd.exe" "[ProjectPath]\[ProjectName].uproject" -ExecutePythonScript="[ProjectPath]\Plugins\UE4PythonScriptSample\Content\Python\[PythonFile].py" -LogCategoryFiles="[ProjectPath]\Saved\Logs\[LogName].log=LogPython"
-
最小限の構成でエディタを起動(アセットのチェックだけとかはこっち)
ex."[EnginePath]\Engine\Binaries\Win64\UE4Editor-Cmd.exe" "[ProjectPath]\[ProjectName].uproject" -run=pythonscript -script="[ProjectPath]\Plugins\UE4PythonScriptSample\Content\Python\[PythonFile].py" -LogCategoryFiles="[ProjectPath]\Saved\Logs\[LogName].log=LogPython"
- パスはフルパスで書く必要がある(UE4Editor-Cmd.exeからの相対でパス解決される)
- pythonscriptの指定は、*"hoge.py arg1 arg2"*のようにコマンド引数を与えることもできる
- Cmdの標準出力にはunreal.logは出力されない(log_warning,log_errorは出力される)
- LogCategoryFilesで、カテゴリ毎の出力ファイルを指定できる(こっちはlogも出力される)
使ってみての雑感
- python2は言語的に終焉に近いようだけど、基本的なことをやる分には問題ないのかなと思う
- 今が触り始めなのと、パッケージ関係を入れ始めたら困り始めるかも
- ただし__init__.py(自作moduleをimportするとき必要)は許しません、あとreloadをいちいち書かないとimport先がリロードされないのは、開発する上で結構めんどくさい
- ググったときのドキュメントは大抵3.x系の内容で、互換性がないものもあるし、python2とかで検索してもヒットしないのはそこそこ困るw
- Pythonで出来ること≒Blueprintで出来ることなので、どちらを使うかは好みになるかも
- 正直、開発初期から導入しておきたかったくらい便利で楽しい(´・ω・`)
Python関係ないけど
- エディタ周りでいろいろ触っていくには、エンジン内部処理を追うためにソースを見ていく必要がある
- 公式のAPIリファレンスは、[Native Types]の項を除いてBP公開クラスを羅列してるだけなので、探すのが大変w
- まずは~Library、~Helperとかでリファレンスをさらうとよいかも
TODO的な、あったらいいな的な?
- ライトビルド(ライトシナリオの切り替えとか)
- アセット名の修正(Prefix,Suffix,ルール付け)
- レベル内のアウトライン整理
- submit履歴を参照して、最後の変更者に通知