언리얼 C++ 기본 타입과 문자열

JungWoo·2023년 9월 8일
0

언리얼 C++ 기본 타입

기본 타입을 따로 지정하는 이유

  • 게임 제작의 특징
    - 데이터 정보가 명확해야 한다
    - 단일 컴퓨터에서 최대 퍼포먼스를 뽑아내야 한다
    - 네트웍 상에서 데이터 통신이 효율적이고 안정적이어야 한다
  • 데이터 타입의 애매 모호함은 게임 개발시 문제를 일으킬 수 있기 때문

언리얼 엔진에서 사용하는 기본 타입 (언리얼 엔진 코딩 표준문서)

언리얼 엔진 코딩 표준문서

bool 타입의 선언

  • 데이터 전송을 고려한 참/거짓 데이터의 지정
  • bool은 크기가 명확하지 않음
  • 헤더에는 가급적 bool 대신 uint8 타입을 사용하되 Bit Field 오퍼레이터를 사용
  • 일반 uint8과의 구분을 위해 b접두사를 사용
  • cpp 로직에서는 자유롭게 bool 사용
// ex
UPROPERTY()
uint8 bNetTemporary:1;

캐릭터(Char) 인코딩

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

  • 문자열 처리 종류
    - Single byte(ANSI, ASCII)
    - Multibyte(EUC-KR, CP949)
    - Unicode(UTF-8, UTF-16)
  • 모든 문자열을 처리하기 위해

- UTF-8 vs UTF-16

캐릭터 인코딩 공식 문서
캐릭터 인코딩 공식 문서

캐릭터 인코딩 공식 문서

캐릭터 인코딩 공식 문서

캐릭터 인코딩 공식 문서

참조 : 캐릭터 인코딩 언리얼 엔진 공식 문서

요약

언리얼 엔진에서는 string을 관리할 때 UTF-16방식의 인코딩을 사용한다.
소스 코드에서 한글을 사용할 경우 UTF-8 방식으로 인코딩하여야 함 (오류 발생 가능)


TCHAR와 FString

  • Unicode를 사용해 문자열 처리를 통일
    - 2byte로 사이즈가 균일한 UTF-16 사용
    - 유니코드를 위한 언리얼 표준 캐릭터(Char)타입 : TCHAR
  • 문자열은 언제나 TEXT 매크로를 사용해 지정
    - TEXT 매크로로 감싼 문자열은 TCHAR 배열로 지정됨
  • 문자열을 다루는 클래스로 FString을 제공함
    - FString은 TCHAR 배열을 포함하는 헬퍼 클래스

FString 구조와 활용

  • 다른 타입에서 FString으로의 변환

    • FString::Printf
    • FString::SanitizeFloat
    • FString::FromInt
  • C런타임 수준 문자열을 처리하는 클래스 FCString

    • ex) 문자열을 찾는 strstr을 사용
  • FString에서 다른 타입으로의 변환 (불안전)

    • FCString::Atoi (문자에서 정수로)
    • FCString::Atof (문자에서 실수로)

TEXT() -> TCHAR 포인터(TCHAR 배열) <-> FString(TCHAR 동적배열 = TArray) <-> FCString
cf) FString에서 TCHAR배열로 변환할 때는 *를 붙여야 한다

ex)
FString Words = TEXT("Hello");
const TCHAR* FStringToChar = *Words;

<.h>
#pragma once

#include "CoreMinimal.h"
#include "Engine/GameInstance.h"
#include "MyGameInstance.generated.h"

/**
 * 
 */
UCLASS()
class UNREALSTRING_API UMyGameInstance : public UGameInstance
{
	GENERATED_BODY()
	
public:
	virtual void Init() override;

private:

};
#include "MyGameInstance.h"

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

	static const TCHAR LogCharArray[] = TEXT("Hello Unreal");
	UE_LOG(LogTemp, Log, LogCharArray);

	// FString = TCHAR Array
	FString LogCharString = LogCharArray;
	// 포인터 연산자를 지정해줘야 한다
	UE_LOG(LogTemp, Log, TEXT("%s"), *LogCharString);

	// const TCHAR* = *FString
	const TCHAR* LogCharPtr = *LogCharString;
	// TCHAR* = *FString.GetCharArray().GetData()
	TCHAR* LogCharDataPtr = LogCharString.GetCharArray().GetData();

	TCHAR LogCharArrayWithSize[100];
	FCString::Strcpy(LogCharArrayWithSize, LogCharString.Len(), *LogCharString);

	// FString::Contains() = FString에 TEXT()의 내용을 포함하는지 확인하는 함수
	// ESearchCase::IgnoreCase = 대소문자 구분 X
	// ESearchCase::CaseSensitive = 대소문자 구분 O
	if (LogCharString.Contains(TEXT("Unreal"), ESearchCase::IgnoreCase))
	{
		// FString::Find() = 단어가 시작되는 위치를 찾는 함수
		int32 Index = LogCharString.Find(TEXT("Unreal"), ESearchCase::IgnoreCase);
		// FString::Mid() = 해당 위치부터 마지막까지의 문자열 반환 함수
		FString EndString = LogCharString.Mid(Index);

		UE_LOG(LogTemp, Log, TEXT("Find, Test: %s"), *EndString);
	}

	FString Left, Right;
	// FString::Split() = TEXT의 단어를 기준으로 문자를 나누는 함수
	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);
}

코드 출력 결과
코드 출력 결과

참조 : FString 언리얼 공식 문서


언리얼이 제공하는 다양한 문자열 처리

FName

  • FString -> FName
  • 애셋 관리를 위해 사용되는 문자열 체계
    • 대손문자 구분 없음
    • 한번 선언되면 바꿀 수 없음
    • 가볍고 빠름
    • 문자를 표현하는 용도가 아닌 애셋 키를 지정하는 용도로 사용. 빌드시 해시값으로 변환

FName 구조와 활용

  • 언리얼은 FName과 관련된 글로벌 Pool 자료구조를 가지고 있음
  • FName과 글로벌 Pool
    • 문자열이 들어오면 해시 값을 추춣래 키를 생성해 FName에서 보관
    • FName 값에 저장된 값을 사용해 전역 Pool에서 원하는 자료를 검색해 반환
    • 문자 정보는 대소문자를 구분하지 않고 저장 (IgnoreCase)
  • FName의 형성
    • 생성자에 문자열 정보를 넣으면 풀을 조사해 적당한 키로 변환하는 작업이 수반
    • Find or Add

문자열 -> FName <-> FNamePool(Key, Value)

참조 : FName 언리얼 공식 문서

FText

  • FString -> FText
  • 다국어 지원을 위한 문자열 관리 체계 (UI에서 사용)
    • 일종의 키로 작용함
    • 별도의 문자열 테이블 정보가 추가로 요구
    • 게임 빌드 시 자동으로 다양한 국가별 언어로 변환
profile
UnrealEngine 꿈나무

0개의 댓글