언리얼 엔진에서 지원하는 C++ 컨테이너 사용 예


언리얼 엔진에서 지원하는 C++ 컨테이너에는 아래와 같은 것들이 있는데, 다른 고급언어에서 지원하는 List, Set, Map 과 같은 컬렉션 API와 유사한 특징을 갖고 있다

 

  • TArray<T> : 원소의 중복허용, 순서유지
  • TSet<T> : 원소의 중복안됨, 순서유지
  • TMap<T,S> : 키, 값의 쌍으로 데이터를 저장함, 키는 중복 안됨



언리얼 엔진에서 BlueprintFunctionLibrary 하위 클래스를 작성하고 아래와 같은 내용으로 TArray<T> 를 테스트한다


TArray<FString> UMyBlueprintFunctionLibrary::ArrayTest()

{

TArray<FString> strArr;


strArr.Add(FString("Smith"));

strArr.Add(FString("Jone"));

strArr.Add(FString("Scott"));

strArr.Add(FString("Andy"));

strArr.Add(FString("Andy")); // 중복저장도 허용되고, 저장순서도 유지된다

strArr.Insert(FString("WARD"),0);


int len = strArr.Num();


//인덱스를 이용한 배열의 원소접근

for (int i = 0; i < len; i++) {

FString name = strArr[i];

}

//반복자를 이용한 배열의 원소접근

for (TArray<FString>::TIterator it = strArr.CreateIterator(); it; ++it) { //후증가는 구현안됨

FString name = *it;

}


return strArr;

}



블루프린트 그래프에서 다음과 같이 TArray<T>를 한다 (C++코드를 수정했으면 블루프린트에서도 살짝 변경하여 다시 저장해주면 제대로 반영되는 것 같다)




TSet<T> 테스트 : 저장 순서가 유지되고 중복저장은 안된다


TSet<int> UMyBlueprintFunctionLibrary::SetTest()

{

TSet<int> set;


set.Add(2);

set.Add(1);

set.Add(3);

set.Add(5);

set.Add(4);


set.Add(5); // 오류는 아니지만 중복저장은 안됨


// TSet은 인덱스를 이용하여 접근할 수는 없다(반복자만 가능)

for (TSet<int>::TIterator it = set.CreateIterator(); it; ++it) { // 후증가 기능은 정의되지 않음

int num = *it;

FString sNum = FString::FromInt(*it);

}

return set;

}



블루프린트에서 다음과 같이 TSet<T>을 테스트할 수 있다




TMap<T,S>의 테스트


TMap<FString, FString> UMyBlueprintFunctionLibrary::MapTest()

{

TMap<FString, FString> map;


map.Add(FString(TEXT("1번")), FString(TEXT("Adam")));

map.Add(FString(TEXT("2번")), FString(TEXT("Marry")));

map.Add(FString(TEXT("3번")), FString(TEXT("Jone")));

map.Add(FString(TEXT("4번")), FString(TEXT("Smith")));

map.Add(FString(TEXT("5번")), FString(TEXT("Andy")));

map.Add(FString(TEXT("5번")), FString(TEXT("Ward"))); // 중복안됨,기존 5번 항목을 덮어씀


FString name = map[FString(TEXT("2번"))];

for (TMap<FString, FString>::TIterator it = map.CreateIterator(); it; ++it) {

FString key = it->Key;     // K는 대문자

FString name = it->Value;  // V는 대문자

}


return map;

}



TMap<T,S>는 블루프린트에서 다음과 같이 테스트할 수 있다


Posted by cwisky
Unreal C++/VS 2017 Setup2017. 11. 23. 14:02

언리얼 엔진에서 C++를 사용하기 위한 VS 2017 Community Edition 설치 및 테스트


언리얼 엔진에서 C++ BlueprintFunctionLibrary 라는 클래스를 상속하여 하위 클래스를 생성하고 static 함수를 선언 및 정의하고 언리얼에서 컴파일만 해주면 그 외의 아무런 설정 없이 블루프린트에서 그 함수를 호출하는 노드를 바로 사용할 수 있다. 

여기서는 Visual Studio 2017 Community Edition을 설치하고 작동하는지 테스트하기 위해서 언리얼 엔진에서 BlueprintFunctionLibrary 기반 클래스를 작성하고 실행해보는 절차까지 안내한다


Unreal Engine 4.15 이상의 버전에 Visual Studio 2017 Community Edition을 설치하고 설정하는 방법

https://docs.microsoft.com/en-us/cpp/build/vscpp-step-0-installation

https://docs.unrealengine.com/en-us/Programming/Development/VisualStudioSetup



테스트 환경

  • Visual Studio 2017 Community Edition
  • Unreal Engine 4.17
  • Windows 8.1, 10




Visual Studio 2017 Community 설치시 확인할 사항

설치 옵션을 선택하는 창에서 아래처럼 Unreal Engine 항목에 선택하면 코딩시에 Code Assistance가 제대로 지원된다




Visual Studio와 Unreal Engine 4를 설치했다 하더라도 Windows SDK가 설치되지 않으면 Unreal Engine에서 C++ 클래스를 생성하더라도 오류가 발생한다. 오류 메시지를 잘 살펴보면 해당 OS의 SDK가 설치되지 않아서 컴파일에 실패한 경우에는 해당 SDK를 다운로드하여 설치해주면 된다.

오류 메시지에는 Windows 8.1 SDK Not installed 와 같은 직접적인 원인이 표시되므로 SDK 버전에 대해서는 고민할 필요가 없다



Visual Studio 설정시 권장되는 설정 사항


VS 2017 Community Edition Recommended Settings

툴바에서 마우스 우측 > 하위항목 맨 아래에서 [사용자 지정] 선택 > 명령 > 도구모음 > 우측의 콤보박스에서 [표준] 선택 > 미리보기 패널에서 [솔루션 구성] 선택 > 우측에서 [선택사항 수정] 선택 > [너비] 항목에 200 입력 > [확인] > 닫기


Add the Solution Platforms Dropdown

툴바에서 거의 끝에 있는 [표준 도구모음 옵션] 을 선택한다

[단추 추가/제거]에 마우스를 올리고 [솔루션 플랫폼]에 체크한다


Turn Off the Error List Window

도구 > 옵션 > 프로젝트 및 솔루션 > [오류로 인해 빌드가 종료될 때 항상 오류 목록표시] 체크해제 > 확인


Show Inactive Blocks 선택해제

도구 > 옵션 > 텍스트 편집기 > C/C++ > 뷰 > 비활성 블록 표시:False > 확인


Disable External Dependencies Folders 항목을 True 설정

도구 > 옵션 > 텍스트 편집기 > C/C++ > 고급 > 외부 종속성 폴더 사용 안함:True 설정 > 확인


Edit & Continue 기능해제

도구 > 옵션 > 디버깅 > 편집하며 계속하기:해제 > 확인


Intellisense, Live Errors, and Squiggles

도두 > 옵션 > 텍스트 편집기 > C/C++ > [고급] 선택 후 아래처럼 설정 > 확인

  • 자동 요약 정보 : True
  • IntelliSense 사용 안 함 : False
  • 자동 업데이트 사용 안 함 : False
  • 오류 보고 사용 안 함 : False
  • 물결선 사용 안 함 : False


Visual Studio 설치 및 설정 후 UE4와 연동 테스트


Unreal Engine 을 실행하고 임의의 템플릿(블루프린트)을 이용하여 프로젝트를 생성한다

Content Browser 영역에서 마우스 우측 > 새 C++ 클래스 > 모든 클래스에 체크 > 검색란에 BlueprintFunctionLibrary를 입력하여 부모  클래스를 선택한다


하단의 [선택] 버튼을 누르면 헤더파일, 소스파일의 파일경로를 묻는데 디폴트로 두고 [클래스 생성] 버튼을 누른다.


Content Browser에 [C++클래스] 노드가 생성되고 그 아래에 C++ 클래스가 생성된다



Conent Browser 에서 C++ 클래스가 보이지 않는 경우

Content Browser 우측 하단의 눈 아이콘(뷰옵션) > [C++ 클래스 표시]



자동으로 Visual Studio가 실행되면서 C++ 프로젝트에 헤더파일과 소스파일 등이 생성된 것이 확인된다. 보이지 않는다면 Visual Studio의 솔루션 탐색기에서 해당파일을 더블클릭하면 에디터에 보이게 된다



헤더파일(*.h)에 다음과 같이 입력한다(적색 부분이 추가된 내용이다)


// Fill out your copyright notice in the Description page of Project Settings.


#pragma once


#include "CoreMinimal.h"

#include "Kismet/BlueprintFunctionLibrary.h"

#include "MyBlueprintFunctionLibrary.generated.h"


/**

 * 

 */

UCLASS()

class CONTAINERTESTMAP_API UMyBlueprintFunctionLibrary : public UBlueprintFunctionLibrary

{

GENERATED_BODY()


UFUNCTION(BlueprintCallable, Category="MyTest")

static FString greetings();

};



소스파일(*.cpp)에 다음과 같이 입력한다(적색 부분이 추가된 내용이다)


// Fill out your copyright notice in the Description page of Project Settings.


#include "MyBlueprintFunctionLibrary.h"


FString UMyBlueprintFunctionLibrary::greetings()

{

return FString(TEXT("Hello World"));

}


Visual Studio에서 위의 내용을 편집한 후에 저장하고 Unreal 레벨 에디터의 툴바에서 [컴파일] 버튼을 누르면 실패, 성공여부가 보여진다


위의 코드가 언리얼에서 컴파일에 성공하면 블루프린트에서 다음과 같이 함수노드를 생성하고 호출할 수 있다



Posted by cwisky

언리얼 Blueprint Function Library를 사용하여 정수배열을 정렬하는 예


테스트 환경

  • Visual Studio C++
  • Unreal Engine 4



블루프린트 프로젝트를 생성한다


Content Browser에서 마우스 우측 > 새 C++ 클래스 > 부모클래스 선택 창에서 [모든 클래스] 항목에 체크하고 Blueprint Function Library 클래스를 검색하여 선택한다. 파일이름을 디폴트로 두고 [선택] 버튼을 누르면 잠시 후 Visual Studio 가 실행되고 헤더파일과 소스파일이 생성된다.

헤더파일과 소스파일에 아래의 내용을 추가하여 저장하고 빌드할 필요는 없다. 언리얼 에디터의 툴바에서 [컴파일] 버튼을 누르면 C++ 컴파일이 시작되고 그 결과 완료 혹은 실패 메시지가 나타난다. 문법적인 오류가 없다면 컴파일에 성공할 것이다.


헤더파일에 다음과 같이 선언한다(적색 부분은 디폴트 내용에 새로 추가된 내용)

// Fill out your copyright notice in the Description page of Project Settings.


#pragma once


#include "CoreMinimal.h"

#include "Kismet/BlueprintFunctionLibrary.h"

#include "MyBlueprintFunctionLibrary.generated.h"


UCLASS()

class BP_CPP_API UMyBlueprintFunctionLibrary : public UBlueprintFunctionLibrary

{

GENERATED_BODY()


UFUNCTION(BlueprintCallable, Category="TestFunction")

static TArray<int32> sort(TArray<int32> arr);

};



소스파일에 다음과 같이 선언한다(적색 부분은 디폴트 내용에 새로 추가된 내용)

// Fill out your copyright notice in the Description page of Project Settings.


#include "MyBlueprintFunctionLibrary.h"


TArray<int32> UMyBlueprintFunctionLibrary::sort(TArray<int32> arr)

{

int tmp = 0;

for (int i = 0; i < arr.Num() - 1; i++) {

for (int j = i + 1; j < arr.Num(); j++) {

if (arr[i] > arr[j]) {

tmp = arr[i];

arr[i] = arr[j];

arr[j] = tmp;

}

}

}

return arr;

}



위에서 생성한 C++ 함수는 언리얼 엔진의 블루프린트 그래프에서 함수노드를 이용하여 사용할 수 있다. 





C++의 Object 파생클래스를 블루프린트에서 사용하는 예


블루프린트 프로젝트에서 C++ Object 파생클래스를 작성하는 절차는 위와 동일하지만 부모 클래스를 Object 로 설정하며 코드 상에서 UCLASS() 매크로를 추가하고 블루프린트에서 Construct Object from Class 노드를 사용하여 파생 클래스의 인스턴스를 생성한다는 점이 다르다


BlueprintFunctionLibrary 파생클래스를 사용하지 않고 Object 파생클래스를 사용해도 된다. BlueprintFunctionLibrary 도 아니고 Actor도 아닌 Object 파생클래스를 C++에서 작성하고 블루프린트에서 사용하려면 클래스 선언문 위에 UCLASS(Blueprintable, BlueprintType) 매크로를 추가해야 하며, 블루프린트에서 호출하려면 Construct Object from Class 노드를 사용하면 된다


Object 파생클래스의 헤더파일 (적색 부분은 Visual Studio에서 추가한 내용)

// Fill out your copyright notice in the Description page of Project Settings.


#pragma once


#include "CoreMinimal.h"

#include "UObject/NoExportTypes.h"

#include "VarTest.generated.h"


/**

 * 

 */

UCLASS(Blueprintable, BlueprintType)

class CONTAINERTESTMAP_API UVarTest : public UObject

{

GENERATED_BODY()


UFUNCTION(BlueprintCallable, Category = "VarTest")

TArray<int> sort(TArray<int> arr);

};



Object 파생클래스의 소스파일 (적색 부분은 Visual Studio에서 추가한 내용)

// Fill out your copyright notice in the Description page of Project Settings.


#include "VarTest.h"


TArray<int> UVarTest::sort(TArray<int> arr)

{

for (int i = 0; i < arr.Num()-1; i++)

{

for (int j = i + 1; j < arr.Num(); j++)

{

if (arr[i] > arr[j])

{

int tmp = arr[i];

arr[i] = arr[j];

arr[j] = tmp;

}

}

}

return arr;

}



Visual Studio에서 위처럼 작성했다면 저장하고 언리얼 에디터의 툴바에서 [컴파일]을 눌러 컴파일을 마치면 블루프린트에서 다음과 같이 Construct Object from Class 노드를 사용하여 인스턴스를 생성하고 그 멤버함수를 호출할 수가 있다



Posted by cwisky