实现游戏的中英文对应
由于界面标题中有中文乱码,这个可以通过修改编译器的编码为UTF-8解决,也可以通过UE4自带的本地化方法解决,自带方法包括:
1. TEXT() 创建一个通用的 String 类型, TEXT("Hello");
2. LOCTEXT() 创建一个本地化文字, LOCTEXT ("ID" "String");
3. NSLOCTEXT() 在一个域名空间内的本地化, NSLOCTEXT (Namespace"," "Name","Hello");
以下为使用2、3两种方法来实现的本地化
新建一个类 SlAiInternation
只需要头文件就好,将项目下的.cpp文件移除,资源文件夹中的文件删除
编辑文件
D:\UE4 Project\UE26.2\CourseProject\SlAiCourse\Source\SlAiCourse\Public\Date\SlAiInternation.h
#include "CoreMinimal.h" class SLAICOURSE_API SlAiInternation { public: static void Register(FText, Value) [ return; ] }; #define LOCTEXT_NAMESPACE "SlAiMenu" /** *主菜单 */ SlAiInternation::Register(LOCTEXT("Menu", "Menu")); SlAiInternation::Register(LOCTEXT("startGame", "startGame")); //开始游戏 SlAiInternation::Register(LOCTEXT("Gameoption", "Gameoption")); //游戏设置 SlAiInternation::Register(LOCTEXT("QuitGame", "QuitGame")); //退出游戏 SlAiInternation::Register(LOCTEXT("NewGame", "NewGame")); //新游戏 SlAiInternation::Register(LOCTEXT("LoadRecord", "LoadRecord")); //加载存档 SlAiInternation::Register(LOCTEXT("ChooseRecord", "ChooseRecord")); //选择存档 /** *进入游戏界面 */ SlAiInternation::Register(LOCTEXT("RecordName", "RecordName")); //存档名 SlAiInternation::Register(LOCTEXT("EnterGame", "EnterGame")); //进入游戏 SlAiInternation::Register(LOCTEXT("EnterRecord", "EnterRecord")); //进入存档 SlAiInternation::Register(LOCTEXT("RecordNameHint", "Input Record Name!")); //输入存档名 SlAiInternation::Register(LOCTEXT("NameRepeatedHint", "Record Name Repeated!")); //输入存档名 /** *游戏设置界面 */ SlAiInternation::Register(LOCTEXT("Chinese", "Chinese")); //中文 SlAiInternation::Register(LOCTEXT("English", "English")); //英文 SlAiInternation::Register(LOCTEXT("Music", "Music")); //音乐 SlAiInternation::Register(LOCTEXT("Sound", "Sound")); //音效 /** *公用 */ SlAiInternation::Register(LOCTEXT("GoBack", "GoBack")); //返回 #undef LOCTEXT_NAMESPACE
/************************************************************************************************ * SlAiInternation::Register(NSLOCTEXT("SlAiMenu", "Menu", "Menu")) * *上方三行代码与这一行代码作用是一样的,区别在于上方三行是将域名放到外面,而NSLOCTEXT是将域名放到里面 * 其他文件中想要调用该本地化文字的时候,可以直接通过 NSLOCTEXT 调用,不用很麻烦的先去声明域名再去调用 LOCTEXT *************************************************************************************************/
NSLOCTEXT 的调用方式
D:\UE4 Project\UE26.2\CourseProject\SlAiCourse\Source\SlAiCourse\Private\UI\Widget\SSlAiMenuWidget.cpp
#include "UI/Widget/SSlAiMenuWidget.h" #include "SlateOptMacros.h" #include "UI/Style/SlAiStyle.h" #include "UI/Style/SlAiMenuWidgetStyle.h" #include "Widgets/Layout/SBox.h" #include "Widgets/Images/SImage.h" #include "Widgets/Text/STextBlock.h" BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION void SSlAiMenuWidget::Construct(const FArguments& InArgs) { MenuStyle = &SlAiStyle::Get().GetWidgetStyle<FSlAiMenuStyle>("BPSlAiMenuStyle"); ChildSlot [ SAssignNew(RootSizeBox, SBox) [ SNew(SOverlay) +SOverlay::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Fill) .Padding(FMargin(0.f, 50.f, 0.f, 0.f)) [ SNew(SImage) .Image(&MenuStyle->MenuBackgroundBrush) ] +SOverlay::Slot() .HAlign(HAlign_Left) .VAlign(VAlign_Center) .Padding(FMargin(0.f, 25.f, 0.f, 0.f)) [ SNew(SImage).Image(&MenuStyle->LeftIconBrush) ] + SOverlay::Slot() .HAlign(HAlign_Right) .VAlign(VAlign_Center) .Padding(FMargin(0.f, 25.f, 0.f, 0.f)) [ SNew(SImage).Image(&MenuStyle->RightIconBrush) ] + SOverlay::Slot() .HAlign(HAlign_Center) .VAlign(VAlign_Top) [ SNew(SBox) .WidthOverride(400.f) .HeightOverride(100.f) [ SNew(SBorder) .BorderImage(&MenuStyle->TitleBorderBrush) .HAlign(HAlign_Center) .VAlign(VAlign_Center) [ SAssignNew(TitleText, STextBlock) .Font(SlAiStyle::Get().GetFontStyle("MenuItemFort") .Text(NSLOCTEXT("SlAiMenu", "Menu", "Menu")) //使用 NSLOCTEXT 宏插入的本地化文字,三个参数为:域名 Key Value ] ] ] ] ]; RootSizeBox->SetWidthOverride(600.f); RootSizeBox->SetHeightOverride(510.f); } END_SLATE_FUNCTION_BUILD_OPTIMIZATION
在UE4中的菜单,Window -> Localization Dashboard
打开本地化设置
我的 Source 文件下包含了所有的头文件,UE4会从该目录下搜索所有有关于 LOCTEXT 以及 NSLOCTEXT 两个宏的本地化文字
Add New Culture 新增中文,并点击 English 前方圆钮将英文设置为默认选项
点击Gather Text寻找本地化文字,下图为寻找结果,找到21个英文语言,有1个中文翻译(这一个是我之前加的,如果从未添加过这里应该是0)
点击添加中文翻译
写入对应的中文,然后保存
点击 Count Words 刷新进度
然后再点击 Compile Text 进行编译,让UE4将这个文件拷贝到 Cultures 本地化文件夹的格式文件中
它会在本地生成两个文件夹 en ch 这里放置翻译的一些内容
这时候在运行游戏,便不会再显示中文乱码
代码控制UI界面的文字显示:
#include "Internationalization/Internationalization.h" //一个关于本地化的头文件 /** *切换语言 */ FInternationalization::Get().SetCurrentCulture(TEXT("en")); //FInternationalization::Get().SetCurrentCulture(TEXT("ch"));
游戏中实现中英文切换
接下来写两个类,来标记游戏中目前是中文还是英文
SlAiTypes 存放基础的数据结构
SlAiDataDandle 来实现切换中英文的方法
SlAiTypes 也不要 .cpp 文件,留一个 .h 文件便可,将其删除,并移出项目
d:\ue4 project\ue26.2\courseproject\slaicourse\Source\SlAiCourse\Public\Data\SlAiTypes.h
#include "CoreMinimal.h" UENUM() enum class ECultrueTeam : uint8 { EN = 0, ZH };
d:\ue4 project\ue26.2\courseproject\slaicourse\Source\SlAiCourse\Public\Data\SlAiDataHandle.h
#include "SlAiTypes.h" #include "CoreMinimal.h" class SLAICOURSE_API SlAiDataHandle { public: SlAiDataHandle(); static void Initialize(); static TSharedPtr<SlAiDataHandle> Get(); //修改中英文 void ChangeLocalizationCultrue(ECultrueTeam Culture); public: /** * 当前语言状态,保存后转换场景后还会用到 * 这里没有使用UE4 GamePlay 框架的 GameInstance,变量直接写到C++类中除非你主动销毁,否则他会一直存在 */ ECultrueTeam CurrentCulture; private: //创建单例 static TSharedRef<SlAiDataHandle> Create(); private: static TSharedPtr<SlAiDataHandle> DataInstance; };
D:\UE4 Project\UE26.2\CourseProject\SlAiCourse\Source\SlAiCourse\Private\Data\SlAiDataHandle.cpp
#include "Data/SlAiDataHandle.h" TSharedPtr<SlAiDataHandle> SlAiDataHandle::DataInstance = NULL; void SlAiDataHandle::Initialize() { if (!DataInstance.IsValid()) { DataInstance = Create(); } } TSharedPtr<SlAiDataHandle> SlAiDataHandle::Get() { Initialize(); return DataInstance; } TSharedRef<SlAiDataHandle> SlAiDataHandle::Create() { /** *MakeShareable 可以用来创建共享指针和共享引用 */ TSharedRef<SlAiDataHandle> DataRef = MakeShareable(new SlAiDataHandle());
return DataRef; } SlAiDataHandle::SlAiDataHandle() { } void SlAiDataHandle::ChangeLocalizationCultrue(ECultrueTeam Culture) { switch (Culture) { case ECultrueTeam::EN: FInternationalization::Get().SetCurrentCulture(TEXT("en")); break; case ECultrueTeam::ZH: FInternationalization::Get().SetCurrentCulture(TEXT("zh")); break; } //赋值 CurrentCulture = Culture; }