関連ブログ
- [UE4][UE5]開発環境の容量を少しでも減らす 2024.08.14UE
- [UE5] PushModel型のReplicationを使い、ネットワーク最適化を図る 2024.05.29UE
- [UE5]マテリアルでメッシュをスケールする方法 2024.01.17UE
CATEGORY
2021.10.27UE4UE/ C++
執筆バージョン: Unreal Engine 4.26 |
みなさまこんにちは。
今回は「指定した文字がフォントに含まれているか調べる方法」及び「それを用いて文字の置換をする方法」について紹介します。
これを用いる事で名前入力やチャット機能などでユーザーが入力した文字が「データ的にはあるけど表示されない」といった状況を回避することができます!
まずはコンパイルを問題なく通すために必要となる前準備をしていきます。
[プロジェクト名].Build.csファイルを開き、以下のように変更してください。
これがないと今後のソースコードで使う関数を呼び出すための参照が足りず、コンパイルする際にエラーが発生します。
1 2 3 4 5 |
//デフォルト PrivateDependencyModuleNames.AddRange(new string[] { }); //変更後 PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" }); |
それでは準備が完了したので、指定した文字がフォントに含まれているか調べる関数を作っていきたいと思います。
まずはエディタから New C++ Class でC++のクラスを作成します。
今回はどこからでも呼び出せるように UBlueprintFunctionLibraryクラスを継承した、UMyBlueprintFunctionを作成します。
ソースコードは以下の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#pragma once #include "CoreMinimal.h" #include "Kismet/BlueprintFunctionLibrary.h" #include "MyBlueprintFunctionLibrary.generated.h" UCLASS() class BLOG_API UMyBlueprintFunctionLibrary : public UBlueprintFunctionLibrary { GENERATED_BODY() public: UFUNCTION(BlueprintPure, Category = "MyBPLibrary") static FString ReplaceUnsupportedCharacter(const UFont *Font, FString SourceStr, FString ReplaceStr); private: static bool IsSupportedCharacter(const UFont *Font, TCHAR Source); }; |
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 40 41 42 43 44 45 |
#include "MyBlueprintFunctionLibrary.h" #include "Engine/Engine.h" #include "Engine/Font.h" #include "Fonts/SlateFontInfo.h" #include "EngineFontServices.h" //文字列内でフォント非対応な文字があれば置き換える FString UMyBlueprintFunctionLibrary::ReplaceUnsupportedCharacter(const UFont *Font, FString SourceStr, FString ReplaceStr) { FString Result; for(TCHAR SourceChar : SourceStr) { if(IsSupportedCharacter(Font, SourceChar)) { //フォントが対応してるので元の文字を使う Result.AppendChar(SourceChar); } else { //フォントが対応していないのでReplaceStrを使う Result.Append(ReplaceStr); } } return Result; } //指定した文字がフォント側で対応されているか調べる bool UMyBlueprintFunctionLibrary::IsSupportedCharacter(const UFont *Font, TCHAR SourceChar) { TSharedPtr<FSlateFontCache> FontCache = FEngineFontServices::Get().GetFontCache(); if(FontCache.IsValid()) { const float FontScale = 1.0f; const FSlateFontInfo FontInfo = Font->GetLegacySlateFontInfo(); FCharacterList& CharacterList = FontCache->GetCharacterList(FontInfo, FontScale); const FCharacterEntry& Entry = CharacterList.GetCharacter(SourceChar, FontInfo.FontFallback); return Entry.Valid; } else { return false; } } |
ソースコード中で特に見ていただきたいのは、IsSupportedCharacter関数です。
こちらの処理はフォント情報を取得し、フォント情報から特定の文字を取り出せたかをbool値で返すというものです。
これを利用することで指定した文字がフォントで対応されているかを調べることができます。
次に見ていただきたいのは、実際にBlueprint(以下BP)で使用するための関数であるReplaceUnsupportedCharacter関数です。
こちらは文字列をFor文で1文字づつに分け、その都度IsSupportedCharacterを実行してフォント非対応の文字であれば指定の文字列に置換するといった処理をしています。
以上で大まかな説明は終わりです。
今回2つの関数に分けた理由は、「指定した文字がフォントに含まれているか調べる」という機能と、「それを用いて文字の置換をする方法」を明確に分ける為でした。
実際に使う際にはIsSupportedCharacter内の36行目まではフォントごとに1度実行すれば使いまわすことできます。非対応の文字を置き換えるという目的のみであれば、2つの関数を1つにまとめた方が無駄がなりますのでお試しください。
1.フォント
まずはプロジェクトに使用するフォントを追加します。
今回の環境ではNotoSansJPを使用しました。
2.ウィジェット
次に確認用のウィジェットを作成します。
「置き換え前となる文字列用」と「置き換え文字用」のTextBoxパーツを配置します。
「非対応文字を置き換えたあとの文字列用」のTextパーツを配置します。
TextBoxの方のフォントはUE4デフォルトフォントを用いるので特に指定せず、Textの方のフォントに先ほど追加したNotoSansJPを指定します。
3.ウィジェットの表示
レベルBPを開いて以下のように組みます。左からウィジェットの作成、画面に追加、カメラ操作を無効化 となっています。
4.パッケージ作成
確認のためにはパッケージを作成します(重要)。理由はエディタ上だと先ほど作成した関数よりも前に文字化けしたとき専用の記号に置き換えられているため、IsSupportedCharacterの処理結果が常にtrueになってしまうからです。
パッケージを作成する前にレベルを保存し、ProjectSettingsからGameDefaultMapに保存したレベルを指定してください。
5.実行して確認
パッケージの作成が完了したら早速起動して、それぞれのTextBoxに入力してみてください。
以下の画像で入力した文字はこちらです。
赤:テスト
橙:테스트
緑:测试
青:℁
置き換え文字:*
想定通りにNotoSansJPで非対応の文字だけが置換されています。
これにてフォント非対応の文字を置換する方法の紹介は終わりとなります。
ありがとうございました。