ブループリントに公開した C++ クラス、関数などの名前のリネーム方法

More than 1 year has passed since last update.

こちらのリンク集にも載せてありましたが、日本語の記事が見当たらなかったので、書いてみました。


ブループリントに公開するとリネームできない!?

C++ で作ったクラス、関数などがブループリントなどのアセット内で使用されていると、その名前がアセット内に保存される仕組みになっています。では、既に使われているクラスや関数の名前を変更すると、どうなってしまうでしょうか?

試してみましょう。

まず、C++ で AMyActor というアクターを作って、レベルに配置します。

Redirector01.png

レベルを保存した後、AMyActorAMyActor2 にリネームします。

そして、先程保存したレベルを開いてみると……

Redirector02.png

なんと、先程配置したはずのアクターが消えてます!

この他にも、レベルブループリントでこのアクターを参照してたら、以下のような警告が出たり……

Redirector03.png

この型のアクターを継承したブループリントのアセットを開こうとすると、以下のようなダイアログが表示されてアセットが開けなかったり……

Redirector04.png

など、名前の変更により様々な問題が発生してしまいます。


名前の変更にはリダイレクター!!

では、一度名前を決めたらもう変更は出来ないのか?というと、変更する方法はあります。

それは、「名前に対するリダイレクター」を作ることです。

「リダイレクター」とは、アセットを移動、もしくはリネームした際に作られる「アセットがどこに移動したのかを示すファイル」のことです。リダイレクターの詳しい説明はヒストリアさんのこちらのページや過去に書いたこちらの記事に載っています。

アセットのリダイレクターはアセットファイルで、かつ自動で生成されていましたが、C++ の名前に対するリダイレクターは、ファイルではなくゲームプロジェクトの DefaultEngine.ini に手動で記述する形になっています。1

では、試しに DefaultEngine.ini を開いて、先程の AMyActor2 にリネームするためのリダイレクターを書いてみましょう。

リダイレクターを記述する際は、以下のルールを守る必要があります。



  • [/Script/Engine.Engine] セクション内に記述する。

  • クラス、関数など、リネーム対象にあったリダイレクターを定義する。
    (今回は、クラス名のリネームということで「ActiveClassRedirects」を使用。

  • クラス名や構造体名の AU などのプレフィックスは除外する。

  • 名前をダブルクォーテーションで括る。

これらを守って書いたものが以下のものになります。


DefaultEngine.ini

[/Script/Engine.Engine] 

+ActiveClassRedirects=(OldClassName="MyActor",NewClassName="MyActor2")

これを記述した状態で先程のアセットを開くと、問題なく開けることがわかります。


名前に対するリダイレクターには種類がある

これでもうリネームしても大丈夫!!と思われるかもしれませんが、実はまだ大丈夫ではないです。

というのも、今回行ったのは「クラス名」のリネームで、「関数名」「変数名」などの他のリネームはこの方法では出来ないからです。

では、どうすればいいのか?というと、実はエンジンの BaseEngine.ini を見るとわかったりします。

この「名前に対するリダイレクター」はエンジン側でも当然使われていて、それが BaseEngine.ini に大量に記述されています。なので、BaseEngine.ini を見れば「変数の時はどうすればいいか?」「関数の時はどうすればいいか?」がわかります。

以下に、BaseEngine.ini で使われていたリダイレクターをまとめました。2

数が多くて検証するのに時間がかかるので、ここではリダイレクター名とその対象、記述例を載せておきます。

リダイレクター名
対象
記述例

ActiveClassRedirects
クラス名 or 列挙型名 or オブジェクト名
+ActiveClassRedirects=(OldClassName="GameInfo",NewClassName="/Script/Engine.GameMode")
+ActiveClassRedirects=(OldClassName="ELockedAxis", NewClassName="EDOFMode")
+ActiveClassRedirects=(OldClassName="PointLightComponent",OldSubobjName="PointLightComponent0",NewSubobjName="LightComponent0")

ActiveStructRedirects
構造体名
+ActiveStructRedirects=(OldStructName="AnimNode_BlendSpace",NewStructName="AnimNode_BlendSpacePlayer")

TaggedPropertyRedirects
メンバ変数名
+TaggedPropertyRedirects=(ClassName="MeshComponent",OldPropertyName="Materials",NewPropertyName="OverrideMaterials")

EnumRedirects
列挙型の要素名
+EnumRedirects=(EnumName="EDOFMode",OldEnumEntry="EDOFMode::X",NewEnumEntry="EDOFMode::YZPlane")

K2FieldRedirects
メンバ関数名
+K2FieldRedirects=(OldFieldName="SceneComponent.AttachTo",NewFieldName="SceneComponent.K2_AttachTo")

K2ParamRedirects
関数の引数名
+K2ParamRedirects=(NodeName="/Script/BlueprintGraph.K2Node_CallFunction", OldParamName="SkeletalMeshComponent.SetAnimInstanceClass.NewBlueprint", NewParamName="NewClass")

ActiveGameNameRedirects
モジュール名
+ActiveGameNameRedirects=(OldGameName="/Script/MovieSceneCoreTypes", NewGameName="/Script/MovieSceneTracks")


一度リネームしたものをもう一回リネームしたい場合は?

では、先程リネームした AMyActor2 を今度は AMyActor3 にリネームしたい場合はどうすればどうすればいいでしょうか?

実際にやってみたところ、こうなりました。


DefaultEngine.ini

[/Script/Engine.Engine] 

+ActiveClassRedirects=(OldClassName="MyActor",NewClassName="MyActor3")
+ActiveClassRedirects=(OldClassName="MyActor2",NewClassName="MyActor3")

なぜ、AMyActror のリダイレクターを残しているのか?というと、一度でもアセットを開いて保存しない限りはアセットの中には AMyActor の名前が残りっぱなしになっているからです。「必ず保存されている」という保証があれば必要ないですが、保証できないのであれば残しておいたほうがいいかと思います。





  1. プラグインのリダイレクターを用意したい場合もゲームプロジェクト側の DefaultEngine.ini に書きます。プラグイン側にそれ相当のファイルがないので……。 



  2. 数が多いので、見落としがあるかもしれません……。