関連ブログ
- [UE4][UE5]開発環境の容量を少しでも減らす 2024.08.14UE
- [UE5] PushModel型のReplicationを使い、ネットワーク最適化を図る 2024.05.29UE
- [UE5]マテリアルでメッシュをスケールする方法 2024.01.17UE
CATEGORY
2020.07.23UE4UE/ C++
執筆バージョン: Unreal Engine 4.25 |
Blueprint Editor で変数・関数の Node を Event Graph 上に配置したときなどに、
それらの名前を人が読みやすいように整形して表示してくれる仕組みがあります。
今回は、この名前の整形処理についてざっくりとお話します。
名前の整形には、FName のメンバ関数である NameToDisplayString() が使われています。
第一引数に渡した文字列を整形した結果を返すというものです。
下記のような整形が行われます。
■ 単語の間にスペースを挿入する
…… 名前がパスカルケースもしくはキャメルケースで書かれていることを想定した処理になっている
…… ただし、特定の単語 (一部の冠詞・前置詞など) はすべて小文字表記にする処理が入っている
…… この処理によって数字が不自然にスペースで区切られないように配慮されている
■ 先頭の文字を大文字にする
…… ただし、bool の名前について、先頭の文字が ‘b’ かつその次の文字が大文字の場合、先頭の ‘b’ を除外する
■ アンダースコアをスペースに置換する
なお、すべて小文字表記となる単語は下記の 15 語です (UE 4.25 時点)。
残念ながらコード内にベタ打ちで書かれているので、.ini を編集して追加・削除するようなことはできません。
In, As, To, Or, At, On, If, Be, By, The, For, And, With, When, From
また、先頭の ‘b’ が除外されるのは、それが bool の名前であるときに限定されています。
NameToDisplayString() は第 2 引数 bIsBool で「bool の名前かどうか」を取るようになっており、
これが false のときには先頭の ‘b’ を除外する処理は走りません。
試しに bool 型でない変数の先頭に ‘b’ を付けてみると、除外されずに残ることがわかります。
詳細な処理内容を知りたい方は、\Engine\Source\Runtime\Core\Private\UObject\UnrealNames.cpp 内の NameToDisplayString() の定義を読んでください。
この整形処理ですが、大文字が連続した場合に単語がスペースで区切られないという問題があります。
エンジン側で用意されている関数の大部分は、UFUNCTION 内のメタデータ指定子 DisplayName に
意図通りにスペースが挿入された名前を設定することでこの問題を回避しているのですが、
下のような一部の関数は対応できていません。
“GetIDFromData” の場合は、 C++ 定義であれば DisplayName に “Get ID from Data” を設定するか、
アンダースコアがスペースに置換されることを利用して “GetID_FromData” とするか、
“Id” 表記にするなどで対応することになります。
最後に、NameToDisplayString() に下記のようなコードを追加して、
上記の大文字連続時の問題の解決を試みることにします (後述しますが、不完全なコードです)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
… bool bWasUpperCase = false; … if ((bUpperCase || (bIsDigit & amp; & !bWasMinusSign)) & amp; & !bInARun & amp; & !bWasOpenParen & amp; & !bWasNumber) { if (!bWasSpace & amp; & OutDisplayName.Len() & gt; 0) { OutDisplayName += TEXT(' '); bWasSpace = true; } bInARun = true; } // 追加はじめ // 今着目している文字とその前の文字が大文字で、 // かつ、次の文字が存在していてそれが小文字の場合、 // 今着目している文字の前にスペースを挿入する if (bWasUpperCase& amp; & bUpperCase & amp; & CharIndex + 1 & lt; Chars.Num() & amp; & FChar::IsLower(Chars[CharIndex + 1])) { OutDisplayName += TEXT(' '); bWasSpace = true; bInARun = true; } // 追加おわり // A lower case character will break a run of upper case letters and/or digits if (bLowerCase) { bInARun = false; } … bWasUpperCase = bUpperCase; … |
この変更により、一部の Node については意図通りに表示されるようになりました。
ただし、この簡素過ぎるコードでは “IDs” が “I” と “Ds” で区切られてしまうようになるなど、別の問題が発生します。
何より、ちょっとした表示上の問題のためにエンジンの根幹部分にある FName のコードを修正するというのは割に合わないため、
修正を加えることは基本的に推奨できません。あくまで一例として参考にしてください。