こんにちは、株式会社Leon Gameworksの遠藤です。

前回は、「スクリプトアクション」を用いたツールの作成方法を解説しました。今回はコンテンツブラウザ上のアセットに対して「スクリプトアクション」を実行するツールを作成していきます。

記事の目次

    0:動作環境

    本記事はUE5.3.2を基に執筆しており、エディタの言語は「英語」でスクリーンショットを撮影しております。

    本記事で作成するツールのプロジェクト一式のデータは以下からダウンロードできます。

    今回のプロジェクトデータ

    1:ツールの概要

    今回は「テクスチャの解像度を一括で変更する」ツールを作成していきます。

    Maximum Texture Size

    テクスチャアセットの[Details]から[Maximum Texture Size]を設定することで、パッケージ時のテクスチャサイズを制限することができます。

    ▲ [Maximum Texture Size]の設定

    通常はこちらの設定を変更することで事足りるのですが、プロジェクトによってはアセットのサイズそのものを減らしたい場合があるため、今回はテクスチャの解像度を直接変更したいと思います。

    ※ Unreal Editor for Fortnite(UEFN)のプロジェクトでもテクスチャのサイズ制限があります。

    2:ツール作成

    2-1:アセットの作成とAsset Action Utilityの概要

    では早速ツールを作成していきます。まずはコンテンツブラウザで右クリックし、[Editor Utilities → Editor Utility Blueprint]を選択します。

    ▲ [Editor Utility Blueprint]アセットの作成

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

    ▲ [Asset Action Utility]を選択

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

    ▲ アセット名を「EUB_ResizeTexture」とする

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

    ▲ テスト用の関数を追加

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

    ▲ [Test Print]の項目が追加されている

    挙動が確認できたところで、テスト用の関数は削除しておきます。

    2-2:リサイズ処理の作成

    サイズごとに項目を用意したいのでまずは汎用的なリサイズ処理を作成します。「ResizeTexture」という関数を作成します。

    ▲ 「ResizeTexture」という関数を作成

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

    ▲ [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」としておきます。

    ▲ 関数にInteger型のピンを追加

    追加した「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]に設定している点に気を付けてください。

    ▲ [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」を設定します。これでテクスチャアセットにのみに表示されるようになりました。

    ▲ 「Texture2D」を設定

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

    ▲ [Supported Conditions]の設定

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

    ▲ [Failure Reason]の設定

    3-2:Undo/Redo操作に対応

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

    ▲ 「Transact Object」ノードの追加

    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)、オムライス駆