2. 3강 언리얼 C++ 기본 타입과 문자열
[목표]
1. 언리얼 환경에서 알아두어야 할 기본 타입과 고려할 점
2. 캐릭터 인코딩 시스템에 대한 이해
3. 언리얼 C++이 제공하는 다양한 문자열 처리 방법과 내부 구성의 이해
언리얼 C++ 기본 타입
- 언리얼에서는 C++의 기본 타입을 사용하지 않는다.
- 기본적으로 C++ 최신 규약에서는 int는 최소 32비트를 보장하도록 규정되어 있다. 이 말은, 특정 플랫폼에서는 64비트로 해석이 될 수 있다는 것이고, 따라서 데이터를 저장할 때 int타입의 크기를 확신할 수 없는 치명적인 문제가 발생하게 된다.
- 따라서 언리얼에서는 int를 사용하지 않고, int32를 사용하도록 되어 있다.
- 데이터 통신같은 바이너리 데이터를 주고 받을 때에는 uint8을 사용한다.
- 캐릭터의 경우 TCHAR사용.
- float와 double은 각각 국제 표준으로 4byte, 8byte로 규정되어 있기 때문에 그대로 사용한다.
- bool타입의 경우 크기가 명확하지 않아, 헤더에는 가급적 bool대신 uint8 타입을 사용하되, Bit Field 오퍼레이터를 사용한다.
uint8 bNetTemporary:1;- 만약 헤더가 아닌 일반 cpp로직에서는 자유롭게 bool을 사용한다.
캐릭터 인코딩
- 컴퓨터의 역사적인 관점에서 ASCII, Multibyte, Unicode 등의 문자열들이 혼합되어 사용되고 있음. 이러한 관점에서 보았을 때 하나로 통일되어 있지 않기 때문에 문자열처리에 문제가 발생하게 된다.
- 이를 해결하기 위해 언리얼에서는
FString,TCHAR(UTF-16, 한 문자당 2byte)라는 매크로 형식을 제공해주고 있으며, 이 하나만 가지고 여러 플랫폼에 맞춰서 처리되기 때문에 이 형식으로만 문자열 처리를 해주면 된다.
TCHAR와 FString
- FString에 대해서 포인터를 사용하는 것에 초점을 맞추기.
- FString의 구조는 어떻게 되어있는지, 그 내부 구조를 이해하기.
- 문자열 관련 코드. 다양한 형식들에 대해 서로 왔다갔다 하는데 이 부분 잘 파악하기.
void Func()
{
TCHAR LogCharArray[] = TEXT("Hello Unreal");
UE_LOG(LogTemp, Log, TEXT("%s"), LogCharArray);
FString LogCharString = LogCharArray;
UE_LOG(LogTemp, Log, TEXT("%s"), *LogCharString);
const TCHAR* LongCharPtr = *LogCharString;
TCHAR* LogCharDataPtr = LogCharString.GetCharArray().GetData();
TCHAR LogCharArrayWithSize[100];
FCString::Strcpy(LogCharArrayWithSize, LogCharString.Len(), *LogCharString);
if (LogCharString.Contains(TEXT("unreal"), ESearchCase::IgnoreCase))
{
int32 Index = LogCharString.Find(TEXT("unreal"), ESearchCase::IgnoreCase);
FString EndString = LogCharString.Mid(Index);
UE_LOG(LogTemp, Log, TEXT("Find Test : %s"), *EndString);
}
FString Left, Right;
if (LogCharString.Split(TEXT(" "), &Left, &Right))
{
UE_LOG(LogTemp, Log, TEXT("Split Test: %s 와 %s"), *Left, *Right);
}
int32 IntValue = 32;
float FloatValue = 3.141592;
FString FloatIntString = FString::Printf(TEXT("Int:%d Float:%f"), IntValue, FloatValue);
FString FloatString = FString::SanitizeFloat(FloatValue);
FString IntString = FString::FromInt(IntValue);
UE_LOG(LogTemp, Log, TEXT("%s"), *FloatIntString);
UE_LOG(LogTemp, Log, TEXT("Int : %s, Float:%s"), *IntString, *FloatString);
int32 IntValueFromString = FCString::Atoi(*IntString);
float FloatValueFromString = FCString::Atof(*FloatString);
FString FloatIntString2 = FString::Printf(TEXT("Int:%d Float:%f"), IntValueFromString, FloatValueFromString);
UE_LOG(LogTemp, Log, TEXT("%s"), *FloatIntString2);
}
FName
- FName : 애셋 관리를 위해 사용되는 문자열 체계.
- 문자 처리를 위해 제공되는 클래스가 아니라, 검색을 위해 제공 되는 클래스이다.
- 대소문자 구분이 없으며, 한 번 선언되면 바꿀 수 없다.
- 가볍고 빠르다.
- 빌드시 해시값으로 변환이 되는 방식이다.
- FText : 다국어 지원을 위한 문자열 관리 체계.
- UI에서 다국어 지원을 할 때 사용됨.
- 일종의 키로 작용하며, 별도의 문자열 정보가 추가로 요구된다.
- 게임 빌드 시 자동으로 다양한 국가별 언어로 변환된다.
void Func()
{
// 대소문자 비교를 하지 않기 때문에 같음 결과가 나온다.
FName key1(TEXT("PELVIS"));
FName key2(TEXT("pelvis"));
UE_LOG(LogTemp, Log, TEXT("FName 비교 결과 : %s"), key1 == key2 ? TEXT("같음") : TEXT("다름"));
// FName을 자주 호출하게 되면 다수의 오버헤드가 발생할 수 있다.
// 이런 경우에는 로컬 스태틱을 사용해주도록 한다.
for (int i = 0; i < 10000; ++i)
{
//좋지 않음.
FName SearchInNamePool = FName(TEXT("pelvis"));
// 아래 선호.
const static FName StaticOnlyOnce(TEXT("pelvis"));
}
}
No Comment! Be the first one.