언리얼엔진5/[Part1] 이득우의 언리얼 프로그래밍

[이득우의 언리얼 프로그래밍 Part1 필기] 3.언리얼C++ 기본타입과 문자열

Rocketbabydolls 2024. 2. 8. 18:39

int 사용 시에는 int32 주로 사용
데이터 통신 등 바이너리 데이터를 주고 받을 때에는 uint8 사용

 


bool 타입

 

  1. 크기가 명확하지 않음
  2. 헤더 파일에는 불리언 데이터 타입을 사용하지 않고 바이트 정보를 사용함

 

:1 을 붙여 데이터 양 최소화 가능 (1비트만 사용)

 

- CPP 파일에서는 bool 자유롭게 사용해도 무방 


캐릭터 인코딩


언리얼이 문자열을 따로 지정하는 이유

- ANSI, ASCII, EUC-KR, CP949 , UTF-8, UTF-16 등의 여러 문자열들이 아직도 사용되고 있다.

언리얼엔진에서는 TCHAR 라는 고유한 문자열 처리 방식을 제공하고 있어 singlebyte, multibyte, Unicode 세 가지 타입을 신경 쓸 필요 없이 TCHAR 하나만 가지고 문자열을 처리해주면 된다.

UTF-8 
- 필요할 때 가변으로 집어넣음 (메모리 적게 사용 / 영문권 1바이트 동아시아 2바이트) 


UTF-16
- 무조건 2바이트 저장
- 언리얼은 내부적으로 모두 UTF-16 사용

소스코드에 한글을 꼭 사용해야 한다면 utf-8 으로 저장해야 한다.

오버라이드된 함수는 Super 무조건 사용!!

문자열을 다양하게 사용하고 싶다면 FString 클래스 사용

 

FSTring의 구조와 활용

 

FCString -> C 라이브러리에서 제공하는 기본적 스트링 관련 함수들을 포함하고 있는 래퍼 클래스

Atoi, Atof 같은 저수준 라이브러리들은 포인터 연산을 하기 때문에 안전하다고는 보장 할 수 없다. 사용 시 주의 필요.

수정을 가하고 싶다면
TCHAR* LogCharDataPtr = LogCharString.GetCharArray().GetData();
이렇게 하면 직접 메모리 접근해서 사용 가능

배열로 복사

TCHAR LogCharArrayWithSize[100];

FCString::Strcpy(LogCharArrayWithSize, LogCharString.Len(), *LogCharString);

 

#include "MyGameInstance.h"

void UMyGameInstance::Init()
{
	Super::Init();

	TCHAR LogCharArray[] = TEXT("Hello Unreal");
	UE_LOG(LogTemp, Log, 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); //SanitierFloat
	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 key1(TEXT("PELVIS"));
	FName key2(TEXT("pelvis"));
	UE_LOG(LogTemp, Log, TEXT("FName 비교 결과 : %s"), key1 == key2 ? TEXT("같음") : TEXT("다름"));

	for (int i = 0; i < 10000; ++i)
	{
		FName SearchInNamePool = FName(TEXT("pelvis"));
		const static FName StaticOnlyOnce(TEXT("pelvis"));
	}

}

 

 

FName & FText

 

FName 은 무언가를 찾기 위한 용도이고, 문자열을 처리하기 위한 클래스가 아니다.

 

 


FName 을 자주 실행되는 함수에 사용하게 되면 오버헤드가 발생할 수 있다.

따라서 Static 사용 권장.

ex) static FName name ~