ぼっちプログラマのメモ

UE4とかUE5とかについて書いたり書かなかったり。

UE4のRetarget Manager にて独自のリグを追加・設定する方法について

アニメーションのリターゲット機能について

UE4 には ボーン構造が異なっているモデル間でも アニメーション を使い回すための仕組みとして、アニメーションリターゲット機能を提供しています。アニメーションリターゲット機能の使い方・注意点に関しては 公式ドキュメント や こちらのYoutube配信 を見ていただくと分かりやすいかと思います。
docs.unrealengine.com
youtu.be

独自のリグを追加・設定するには

リターゲット機能を使う過程でRetarget Manager上でリグの設定をする必要があるのですが、デフォルトですとエンジン標準のHumanoid Rig しか選択できません。

f:id:pafuhana1213:20200703153917g:plain

しかし、プロジェクトによっては 独自のリグを設定して使いまわしたいケースもあるかと思います。ということで、独自のリグ設定を作成・設定する方法について説明します。といっても、簡単です!!!

続きを読む

特定のBlueprint , UMG にて Tickノードが使われているかをチェックする方法について

はじめに

Tick ノードは便利ではありますが、多くのActor, UMG が Tick ノードを使用するとパフォーマンス面で問題が発生する可能性が出てきます。
(特にモバイル や コンソールタイトルにて)

Unreal Engine 4を使って地球を衛る方法 ( p109 より Tickの話 )
UE4におけるレベル制作事例 ( p14 より Tickの話 )
[CEDEC2018] UE4で多数のキャラクターを生かすためのテクニック ( p193 より Tickの話 )

そして、プロジェクト終盤で Tick 負荷が問題になると大変なことになりがちです。なぜなら、Tickを使わないように実装を大きく変更することになるためです。そのため、日々 Tickをなるべく使わないように心がけたり、Tick警察の方が目を光らせることが重要になります。

Tick警察のお供として有名なのが、 dumpticks コマンドです。これで ゲーム中に動いている Tick を洗い出すことができます。

f:id:pafuhana1213:20200626184626p:plain
[CEDEC2018] UE4で多数のキャラクターを生かすためのテクニック p195より

しかし、ゲームを実際に動かす必要があるため、プロジェクトの規模が大きくなるほどチェックが大変になります。また、ログに出力されるだけなので、例えばCSVなどにまとめたい場合は抽出・整形する必要があります。

また、「Find In Blueprints」機能を使って 文字列検索から Tick ノードを抽出することもできますが、全BPが対象になるので時間がかかったり、結果をまとめづらいなどの問題があります。

f:id:pafuhana1213:20200626191716p:plain

そこで今回紹介したいのが、特定のBP・UMG アセットのEvent Graph にて Tick ノード が存在するか否かを自動的にチェックする方法です。こちらであればゲームを実際にプレイする必要はありませんし、その結果をCSV などに自動的にまとめることができます。

続きを読む

Anim Nodeに不正な値が設定された際に、ノードを Warning / Error 表示にしたり AnimBPをコンパイルエラーにする方法について

ログにErrorやWarning出しても気づかない可能性があるので、NodeをError, Warning状態にしたりエラーを発生させようというお話です。なお、AnimNode, AnimGraphNode という単語が出てきますが本記事ではそれについて解説しません。以下の記事が参考になるかと思います
UE4 アニメ―ションノードの作成(ボーンのトランスフォーム)を試してみる - Qiita

はじめに

自作の疑似物理プラグインKawaii Physics」にて、Anim Nodeをとある設定にするとクラッシュするという報告を受けました。

f:id:pafuhana1213:20200516165718p:plain
Rootと同じボーンをExcludeBoneに指定するとクラッシュするバグを修正 by kyi · Pull Request #12 · pafuhana1213/KawaiiPhysics · GitHub


クラッシュを回避すること自体は簡単だったのですが、事実上ノードが機能しなくなるので「不正な値がノードに設定されているよ!修正してね!」ということを作業者に伝えたい所です。また、ログに出力する対応が実装楽ですが…ログを確認してくれないことは稀によくあるので効果としては薄くなることが多いです。
[UE4] UE_LOGについてあれこれ|株式会社ヒストリア


ということで、Anm Nodeに不正な値が設定された際に「問題が発生していることがひと目で分かる」 & 「修正を促す」方法を探して見つけたのが、ValidateAnimNodePostCompile 関数です。下図のように、ERROR! や WARNING! 表示にできる上にAnimBPのコンパイルエラーも起こすことができます!
f:id:pafuhana1213:20200516170926p:plain

コンパイルエラーを起こせるのがとても素敵です。エラーを修正しないとAnimBPを動作させることができないので作業者に修正を強いることができます。また、パッケージ作成時にも同様にError / Warning出力 & パッケージ作成が発生するため、不正な値が入っている状態でパッケージが作られてしまうことを回避できます!

それではValidateAnimNodePostCompile 関数をどのようにして使うのかについて説明します。といっても超簡単です。

続きを読む

【UE4 Android】アプリのバージョン情報(VersionCode, VersionName)を設定・取得する方法について

記事作成のリハビリを兼ねて、先日調べた内容をサクッと書いてみる
検証バージョンは UE4.25.0

はじめに

Androidアプリのバージョン情報には整数のVersionCode と 文字列の VersionNameの2つがあります。
VersionCodeはストア上での管理で用いられるものです。そして、過去にストアにアップロードしたVersionCodeとの重複が許されないため、ストアにアップするたびに値を追加する必要があります。
VersionNameはユーザへの表示のみを目的としたもので自由に設定することが可能です(例:1.2.3-beta)

参考:
アプリのバージョニング  |  Android デベロッパー  |  Android Developers
versionCodeとversionNameの 違い | アプリ開発のお勉強! アプリリ

バージョン情報の設定方法について

一般的なAndroid開発の場合は build.gradle という名前のファイルにVersionCode, VersionNameを記述するのですが、UE4を使ったAndroid開発の場合はプロジェクト設定で記述することになります。
f:id:pafuhana1213:20200509161407p:plain

上の赤枠のStore Version が Version Code、下の赤枠のVersion Displayが Version Name にあたります。
(名前合わせたほうが混乱しなかったのでは…)

Store Version Offsetで設定した値は、横にある( )内のCPUをサポートするアプリのStore Version に加算されます。そのため、例えばプロジェクト設定のPlatform - Android にあるBuildカテゴリの設定を以下のようにすると、作成したパッケージ( APK )のVersionCodeは10+1=11になります。
f:id:pafuhana1213:20200509162156p:plain

ここでカンの良い人は ↑↑図のStore Version Offsetの設定は破綻する可能性があることに気づきます!いったい何が問題なのでしょうか…?






はじめに設定した通り、Version Codeは重複が許されません。そのため、armv7 対応版と arm64対応版をそれぞれストアにアップするプロジェクトの場合、 Store Versionを「11」に設定してアップしようとすると armv7 版は VersionCodeの重複が原因で失敗するはずです。

そのため、実際にStore Version Offsetを運用する際は以下のように重複を回避することを考慮する必要があります。ちなみに、 パッケージが1種類だけプロジェクトの場合は Store Version Offsetを 初期値の0から変更する必要はありません。
f:id:pafuhana1213:20200509163248p:plain

バージョン情報の取得方法について

アプリを更新するかしないかの判定など、 アプリ起動中にStoreVersionを知りたいケースが時々あるかと思います。ということで取得方法についてもご紹介。

プロジェクト設定で設定したStoreVersion や VersionNameなどは UAndroidRuntimeSettings で保持されています。そのため、

.h ファイル

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "AndroidRuntimeSettings.h"
#include "MyBlueprintFunctionLibrary.generated.h"

/**
 * 
 */
UCLASS()
class BUILD0425_API UMyBlueprintFunctionLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()

	UFUNCTION(BlueprintCallable)
	static int GetStoreVersion();

};

.cpp ファイル

#include "MyBlueprintFunctionLibrary.h"

int UMyBlueprintFunctionLibrary::GetStoreVersion()
{
	return GetMutableDefault<UAndroidRuntimeSettings>()->StoreVersion;
}

.build.cs 以下の内容を追加

PrivateDependencyModuleNames.AddRange(new string[] {"AndroidRuntimeSettings" } );

とすることで、StoreVersionを取得することが可能です。
f:id:pafuhana1213:20200509164548p:plain


VersionCode ではなく、StoreVersionであることに注意です! 繰り返しになりますが、VersionCode は StoreVersion とStore Version Offset を足したものです。そのため、VersionCodeの値が欲しい場合は UAndroidRuntimeSettingsが持つ以下のプロパティの値も取得する必要があります。

// Offset to add to store version for APKs generated for armv7
UPROPERTY(GlobalConfig, EditAnywhere, Category = "APK Packaging", meta = (DisplayName = "Store Version offset (armv7)"))
int32 StoreVersionOffsetArmV7;

// Offset to add to store version for APKs generated for arm64
UPROPERTY(GlobalConfig, EditAnywhere, Category = "APK Packaging", meta = (DisplayName = "Store Version offset (arm64)"))
int32 StoreVersionOffsetArm64;

// Offset to add to store version for APKs generated for x86_64
UPROPERTY(GlobalConfig, EditAnywhere, Category = "APK Packaging", meta = (DisplayName = "Store Version offset (x86_64)"))
int32 StoreVersionOffsetX8664;

おしまい

余談:
In-app updates for games のベータが最近公開されたけども今後はこれが主流になっていくのかしら…?
developers-jp.googleblog.com

UE4.23から入った「Editor Validator Subsystem」を使って、アセット保存時などで走るチェック処理(Validate Assets)を拡張しよう!

追記

公開当初は「4.24から入った」というタイトルでしたが…4.23からでしたああああああああああああ
申し訳ありませんんんんんんんんんんんんんんんんんんんんんんんんんんんんんんんんんんんんんんんんn

はじめに

SubSystemって何?という方はまず以下のページをご確認ください。
プログラミング サブシステム | Unreal Engine ドキュメント

UE4.24でEdiorSubSystem継承のSubSystemが幾つか追加されています。そして、その中のEditor Validator Subsystemはアセット保存時などで走るチェック処理(Validate Assets)を簡単に拡張できるという非常に強力な仕組みです!例えば「対象のStatic MeshアセットがLODを持っていない場合はエラーを出す」というチェック・通知処理をBPでサクッと作ることができます

このような仕組みを用意することで「不適切な設定なアセットが混じることで余分な負荷・エラーが発生する」ことを防止できます。特に中規模・大規模プロジェクトでは致命的になりがちなので早めの段階で用意しておきましょう!

Editor Validator Subsystemの使い方

「対象のStatic MeshアセットがLODを持っていない場合はエラーを出す」を例にどのようにしてEditor Validator Subsystemを使うのかを説明します。

Editor Utility Blueprintを作成

f:id:pafuhana1213:20191231221303p:plain
f:id:pafuhana1213:20191231221737p:plain
はじめに、EditorValidatorBaseクラスをベースにしてEditor Utility Blueprintを作成します。この作成したBPにて「チェック対象にするクラスの指定」と「対象のアセットに対して行うチェック処理」を実装していきます。

チェック対象にするクラスを指定

f:id:pafuhana1213:20191231221942p:plain
f:id:pafuhana1213:20191231222034p:plain
まずはCan Validate Asset関数をオーバーライドし、どのアセットクラスを対象とするか指定します。今回はStatic Meshアセットを対象とするので上図のようにします。

対象のアセットに対して行うチェック処理を実装

f:id:pafuhana1213:20191231223442p:plain
f:id:pafuhana1213:20191231224247p:plain
次にValidate Loaded Asset関数をオーバーライドし、チェック処理の内容を書いていきます。

チェック処理を通過した場合は、Asset Passesノードを呼び、ReturnノードでValidを返します。
チェック処理に引っかかった場合は、Asset Failsノードを呼び、ReturnノードでInvalidを返します。このAsset Failsノードの各引数ピンで指定する内容はエラー画面にて表示されるのでちゃんと設定しましょう!

Editor Validator SubsystemにEditor Utility Blueprintを登録(新規作成時のみ)

f:id:pafuhana1213:20191231230854p:plain
次に、Add Validatorノードを使うことで実装したチェック処理をEditor Validator Subsystemに登録します。
(BPの場合、Editor Validator SubsystemはEditor Scripting系のBPからしかアクセスできないため、EditorUtilityWidgetなどで実装する必要があります)

なお、エディタ起動時に各EditorValidatorBase継承のBPは自動的にEditor Validator Subsystemに登録されます。 そのため、上記の処理はEditorValidatorBase継承のBPの作成した後にエディタを再起動すれば不要です。(UEditorValidatorSubsystem::Initialize参照)

アセットのチェック処理を走らせてみよう

f:id:pafuhana1213:20191231232314p:plain
これで準備完了です!試しにLODを持っていないStatic Meshアセットを保存するか、右クリックメニューからチェック処理(Validate Assets)を走らせてみましょう!

f:id:pafuhana1213:20191231232401p:plain
こんな感じにエラーが出ます!最前面にウィンドウが出てくるので、ログに出力する場合と違って無視される可能性が低い…かと思います!

f:id:pafuhana1213:20191231232522p:plain
また、EditorUtilityWidgetなどから明示的にチェック処理を走らせることもできます。そのため、AssetRegistryを使って自動抽出したアセットに対してチェック処理を走らせたりすることができます。

最後に

簡単ではありましたが、Editor Validator Subsystemを使ってアセットのチェック処理を拡張する方法について紹介しました!実装が簡単な上に、エンジン標準のチェック処理に追加する形になるのでワークフローも組みやすいかとと思います。また、ログ出力と違って最前面にエラー文を出せるというのは大きな強みかと思います!是非試してみてください!

おまけ

具体的にどういう仕組みになっているのか知りたい方は UEditorValidatorSubsystem::ValidateAssets の実装をご確認ください。

おしまい

UE4標準のTimeSynth機能を使ってイントロ付きループを実装してみた

ガチ勢の皆様へ

少し長くなるかもなので先に結論から

  • ループマーカー対応の話ではありません。イントロ用・ループ用のサウンドアセットを個別に用意する必要があります
    • ゴメンナサイ
  • BPMと小節・伯単位による管理が可能になったという話です
  • アセット側で再生する小節・拍数などの設定ができますが、BPを使った実装も『少し』必要です
  • UE4.24現在でもベータ機能です
  • 処理負荷が増えるのでご注意ください
  • ○DXか○MODか○wise使えばいいじゃん…という言葉は聞こえません。…聞こえないって言ってるだろ!!!

はじめに

ステージ開始時にBGMのイントロ部分を再生し、その後はループ部分を流す『イントロ付きループ』はゲームでよく見ます(聞きます?)。…が、UE4の標準機能で実装すると様々な工夫・妥協をする必要がありました。

詳細は上記の記事を見ていただくとして…問題を簡単にまとめると以下の通りです。

  • BP, SoundCueにおけるDelayノードでは精度が足りず、イントロとループは自然にならない・安定しない
    • シームレスな音楽の連続再生を実現するにはサンプリングレートでのタイミング精度が求められる
      • 原理的に48kHzの音声ファイルなら、1秒間に48000フレーム
    • Fade In/Outによるクロスフェードでごまかす手もあるが使えないケースがある上に実装コストが少し高い

UE4初期からこの問題を抱えており、個人的にもずっとモヤモヤしていたのですが…
UE4.22で入ったTimeSynth機能を使うことで
高精度かつ(比較的)簡単にイントロループを実現可能になりました!

www.youtube.com
ということで実装してみました。素人耳ですが…たぶんいい感じかと思います!!!(音飛びは録画の問題
以降は↑の作業手順について自分用メモも兼ねて書いていきます。

続きを読む

2019年内でリリースされたUE4の各バージョンを復習してみる - UE4.22編 - (順次更新)

はじめに

年末年始で思ってたよりも時間が取れたので、
2019年内にリリースされたUE4の各バージョン(UE4.22, 23, 24)を復習。
全部はしない上にメモ代わりなので雑な文章になると思います。ご了承くださいましまし
docs.unrealengine.com

続きを読む