實作遊戲的中英文對應
由于界面标題中有中文亂碼,這個可以通過修改編譯器的編碼為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;
}