こんにちは、株式会社Leon Gameworksの遠藤です。
前回は、「スクリプトアクション」を用いたツールの作成方法を解説しました。今回はコンテンツブラウザ上のアセットに対して「スクリプトアクション」を実行するツールを作成していきます。
0:動作環境
本記事はUE5.3.2を基に執筆しており、エディタの言語は「英語」でスクリーンショットを撮影しております。
本記事で作成するツールのプロジェクト一式のデータは以下からダウンロードできます。
1:ツールの概要
今回は「テクスチャの解像度を一括で変更する」ツールを作成していきます。
Maximum Texture Size
テクスチャアセットの[Details]から[Maximum Texture Size]を設定することで、パッケージ時のテクスチャサイズを制限することができます。

通常はこちらの設定を変更することで事足りるのですが、プロジェクトによってはアセットのサイズそのものを減らしたい場合があるため、今回はテクスチャの解像度を直接変更したいと思います。
※ Unreal Editor for Fortnite(UEFN)のプロジェクトでもテクスチャのサイズ制限があります。
2:ツール作成
2-1:アセットの作成とAsset Action Utilityの概要
では早速ツールを作成していきます。まずはコンテンツブラウザで右クリックし、[Editor Utilities → Editor Utility Blueprint]を選択します。

親クラスに[Asset Action Utility]を指定します。

アセットが作成されるので、アセット名を「EUB_ResizeTexture」とします。

アセットを開き、まずはテスト用にPrintStringを実行するだけの関数を追加しました。

アセットを右クリックすると、[Scripted Asset Actions → Test Print]が追加されており、実行するとビューポート上にテキストが表示されます。Actor Action Utilityと同様に関数を追加するだけで、このようなメニューを追加することができます。

挙動が確認できたところで、テスト用の関数は削除しておきます。
2-2:リサイズ処理の作成
サイズごとに項目を用意したいのでまずは汎用的なリサイズ処理を作成します。「ResizeTexture」という関数を作成します。

この関数は直接メニューから呼び出さないので[Details]から[Call In Editor]のチェックを外します。そうすることでメニューの項目に表示されなくなります。

はじめに選択中のテクスチャアセットを取得します。選択中のアセットはこれまでの記事でも何度か使用した[Get Selected Assets]ノードで取得し、「Texture2D」クラスでキャストします。

取得したテクスチャアセットをローカル変数に代入します。

次に[Sequence]ノードを追加し、その先の処理でテクスチャ設定をローカル変数に保存しておきます。プロパティはブループリントからもアクセスできるため、代入ノードを1つ1つ配置すれば可能なのですが、冗長になってしまうので今回はC++で構造体を定義し、構造体生成用の関数を用意しました。

ヘッダー
#pragma once
#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "ResizeTextureFunctionLibrary.generated.h"
USTRUCT(BlueprintType)
struct FResizeTextureSettings
{
GENERATED_USTRUCT_BODY()
UPROPERTY(BlueprintReadWrite)
uint32 CompressionNoAlpha : 1;
UPROPERTY(BlueprintReadWrite)
uint32 bFlipGreenChannel : 1;
UPROPERTY(BlueprintReadWrite)
bool bUseNewMipFilter;
UPROPERTY(BlueprintReadWrite)
TEnumAsByte<enum TextureMipGenSettings> MipGenSettings;
UPROPERTY(BlueprintReadWrite)
int32 LODBias;
UPROPERTY(BlueprintReadWrite)
TEnumAsByte<enum TextureCompressionSettings> CompressionSettings;
UPROPERTY(BlueprintReadWrite)
TEnumAsByte<enum TextureGroup> LODGroup;
UPROPERTY(BlueprintReadWrite)
uint8 SRGB : 1;
UPROPERTY(BlueprintReadWrite)
uint8 bNormalizeNormals : 1;
UPROPERTY(BlueprintReadWrite)
uint8 bUseLegacyGamma : 1;
};
UCLASS()
class EUTOOLS04_API UResizeTextureFunctionLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable)
static FResizeTextureSettings CreateResizeTextureSettings(UTexture* Texture);
};
ソース
#include "ResizeTextureFunctionLibrary.h"
FResizeTextureSettings UResizeTextureFunctionLibrary::CreateResizeTextureSettings(UTexture* Texture)
{
FResizeTextureSettings OutSettings;
OutSettings.CompressionNoAlpha = Texture->CompressionNoAlpha;
OutSettings.bUseNewMipFilter = Texture->bUseNewMipFilter;
OutSettings.bFlipGreenChannel = Texture->bFlipGreenChannel;
OutSettings.MipGenSettings = Texture->MipGenSettings;
OutSettings.LODBias = Texture->LODBias;
OutSettings.CompressionSettings = Texture->CompressionSettings;
OutSettings.LODGroup = Texture->LODGroup;
OutSettings.SRGB = Texture->SRGB;
OutSettings.bNormalizeNormals = Texture->bNormalizeNormals;
OutSettings.bUseLegacyGamma = Texture->bUseLegacyGamma;
return OutSettings;
}
次にリサイズしたいサイズのレンダーターゲットを生成し、元のテクスチャアセットを上書きする処理を作成していきます。レンダーターゲットについては公式ドキュメントを参照してください。
[Sequence]ノードの先にレンダーターゲットを生成する処理を作成し、こちらもローカル変数に保存します。

サイズを指定できるように関数の引数にInteger型のピンを追加します。ピンの名前は「Size」としておきます。

追加した「Size」ピンのGetノードをレンダーターゲット生成箇所に配置し、[Create Render Target 2D]の[Width]ピンと[Height]ピンに繋げます。これで指定したサイズのレンダーターゲットが生成される処理が完成しました。

生成したレンダーターゲットに保存済みのテクスチャ設定を適用します。こちらも同様にC++で関数を用意していますが、ブループリントでも記述可能です。

ヘッダー
UFUNCTION(BlueprintCallable)
static void ApplyResizeTextureSettings(UTexture* TargetTexture, const FResizeTextureSettings& Settings);
ソース
void UResizeTextureFunctionLibrary::ApplyResizeTextureSettings(UTexture* TargetTexture, const FResizeTextureSettings& Settings)
{
TargetTexture->CompressionNoAlpha = Settings.CompressionNoAlpha;
TargetTexture->bUseNewMipFilter = Settings.bUseNewMipFilter;
TargetTexture->bFlipGreenChannel = Settings.bFlipGreenChannel;
TargetTexture->MipGenSettings = Settings.MipGenSettings;
TargetTexture->LODBias = Settings.LODBias;
TargetTexture->CompressionSettings = Settings.CompressionSettings;
TargetTexture->LODGroup = Settings.LODGroup;
TargetTexture->SRGB = Settings.SRGB;
TargetTexture->bNormalizeNormals = Settings.bNormalizeNormals;
TargetTexture->bUseLegacyGamma = Settings.bUseLegacyGamma;
}
さらに[Sequence]ノードの先にレンダーターゲットにテクスチャを描画する処理を追加します。

[Draw Texture]ノードの入力ピンでは、[Blend Mode]を[Opaque]に設定している点に気を付けてください。

最後にレンダーターゲットをテクスチャアセットに変換し、保存しておいたテクスチャ設定を適用します。

関数の処理の全容はこのようになりました。画像を拡大してご覧ください。

2-3:解像度別のメニューを作成
リサイズ用の関数が用意できたので、解像度別に関数を追加します。作成した関数は「Resize」カテゴリに登録しておきます。また、「スクリプトアクション」はメニュー表示時に並び順が自動でソートされてしまうため、関数名の頭に番号を振っておきます。

各関数では[Resize Texture]関数を呼び、引数に各解像度を指定します。

コンテンツブラウザでテクスチャアセットを右クリックすると、[Scripted Asset Actions → Resize]からメニューが表示されるようになりました。

実際に4Kのテクスチャを512ピクセル四方に落としてみました。これでツールの完成です。

3:追加機能
3-1:表示するアセットの制限
ここまでで実装したツールでは、全アセットで右クリックした際にメニューが表示されてしまいます。今回はテクスチャアセットにのみ絞りたいため、表示するアセットを制限したいと思います。
「EUB_ResizeTexture」を開き、[Class Defaults]をクリックすると[Details]パネルに表示するアセットを制限する設定が表示されます。

[Supported Classes]の要素を追加し、「Texture2D」を設定します。これでテクスチャアセットにのみに表示されるようになりました。

また、本記事では使用しませんが、[Supported Conditions]を設定することでさらにフィルタすることができます。

[Failure Reason]を設定すると、フィルタで弾かれたアセットで実行する際にテキストが表示されます。

3-2:Undo/Redo操作に対応
「ResizeTexture」関数のキャストの後に「Transact Object」ノードを挟むと[Ctrl]+[Z]で実行できるUndo操作(巻き戻し操作)やRedo操作に対応することができます。

4:まとめ
前回に続き、スクリプトアクションについて解説しました。本記事で作成するツールのプロジェクト一式のデータは以下からダウンロードできます。
今回のプロジェクトデータ
株式会社Leon Gameworks
●公式サイト
www.leon-game.co.jp
●X(Twitter)
@Leon_Gameworks

トンコツ(遠藤俊太)
●トンコツ開発ブログ
shuntaendo.hatenablog.com
●X(Twitter)
@tonkotsu3656
TEXT_トンコツ(Leon Gameworks)
EDIT_小村仁美 / Hitomi Komura(CGWORLD)、オムライス駆