Unreal C++/Log2017. 11. 25. 11:46

언리얼 엔진에서 디버그 메시지를 출력(Log)하는 다양한 방법


https://wiki.unrealengine.com/Logs,_Printing_Messages_To_Yourself_During_Runtime


로그 출력창 열기

창 > 개발자 툴 > 출력로그


UE_LOG(LogTemp, Warning, TEXT("Your message"));


로그레벨 지정자

- Fatal : 로그파일과 콘솔에 항상 출력되며 프로그램이 종료한다

- Error : 적색으로 콘솔과 파일에 출력된다

 - Warning : 황색으로 콘솔과 파일에 출력된다

- Display : 콘솔과 파일에 출력된다

 - Log : 파일에 출력된다. 에디터에서 실행할 때는 콘솔에도 출력된다

- Verbose : 로그파일에만 출력된다

- VeryVerbose : 로그파일에만 출력되며 매우 상세한 메시지가 출력된다




사용예 (한글이 깨지는 경우에는 이 페이지 하단 내용 참조)

UE_LOG(LogTemp, Warning, TEXT("Hello %s"), TEXT("World"));

UE_LOG(LogTemp, Warning, TEXT("Hello %s, %d, %f"),TEXT("World"), 100, 3.14);

UE_LOG(LogTemp, Warning, TEXT("플레이어 이름: %s"), TEXT("홍길동"));


FString fs(TEXT("홍길동"));

UE_LOG(LogTemp, Warning, TEXT("플레이어:%s, 점수:%d"), *fs, 89);



콘솔이 아닌 스크린에 로그 출력하기

#include <EngineGlobals.h>

 #include <Runtime/Engine/Classes/Engine/Engine.h>

 // ...

 GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("This is an on screen message!"));

 GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Some variable values: x: %f, y: %f"), x, y));



첫번째 아규먼트: 키, -1을 키로 가진 메시지는 서로 덮어쓰지 않고 다른 행에 출력된다. 양수를 키로 사용하면 뒤에 오는 로그가 앞의 로그를 덮어쓰게 된다
두번째 아규먼트는 출력할 기간(초)이다

위의 방법을 조금 더 편리하게 사용하려면 다음과 같이 매크로를 선언하여 사용하면 된다

#include <EngineGlobals.h>
#include <Runtime/Engine/Classes/Engine/Engine.h>

#define print(text) if (GEngine) GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::White,text)

//

print(FString::Printf(TEXT("변수의 값 확인: x: %f, y: %f"), 2.71818, 3.14));



스크린에 한글을 출력하는 예

#include <EngineGlobals.h>

#include <Runtime/Engine/Classes/Engine/Engine.h>

............

GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("한글: x: %f, y: %f"), 100, 100));


출력로그에 한글 출력하기

UE_LOG(LogTemp, Warning, TEXT("플레이어 이름: %s"), TEXT("홍길동"));


C++에서 블루프린트로 한글을 리턴하여 스크린에 출력하려는 경우

FText t = FText::FromString(TEXT("Hello 한글"));

return t; // 리턴된 한글 텍스트는 블루프린트를 사용하여 스크린에 출력했을 때 깨지지 않았다



스크린이나 출력로그에서 한글이 깨지는 경우

만약 Visual Studio 2017 을 이용하여 C++ 코드를 작성하고 언리얼 엔진에서 컴파일한 후에 위의 코드를 실행했을 때 화면이나 출력로그에 표시된 한글이 깨져 있다면 Visual Studio에서 파일을 [다른이름으로저장]할 때 저장버튼 우측에 있는 작은 삼각형을 누르고 [인코딩하여 저장]을 선택하면 다양한 인코딩을 선택할 수 있다.

Visual Studio2017에서는 디폴트로 [한국어-코드페이지 949]로 설정되어 있는데 [유니코드(서명이 있는 UTF-8) - 코드페이지 65001] 으로 변경한 결과 한글이 깨지는 문제가 해결되었다

https://msdn.microsoft.com/ko-kr/library/dxfdkfke.aspx




Posted by cwisky
Unreal C++/Custom Object2017. 11. 23. 22:00

C++에서 작성된 Object 파생 클래스를 블루프린트에서 사용하는 방법


C++에서 Actor 파생 클래스를 생성하면 블루프린트에서도 아무런 설정 없이도 Spawn Actor From Class 노드를 사용하여 인스턴스를 사용할 수가 있다


그러나 C++에서 생성한 Object 파생 클래스는 Spawn Actor from Class노드를 사용할 수 없으므로 약간 설정을 달리해야 블루프린트에서 사용할 수가 있다


C++에서 Object를 파생한 클래스를 선언할 때 클래스 선언문 위에 언리얼 매크로인 UCLASS(Blueprintable, BlueprintType)를 선언해야 한다. 그리고 블루프린트에서 호출하는 속성이나 함수에는 UPROPERTY(), UFUNCTION() 매크로를 추가해야 한다


UCLASS(Blueprintable) : C++ 클래스를 기반으로 블루프린트 클래스로 파생할 수 있다

UCLASS(BlueprintType) : C++ 클래스의 변수를 블루프린트에서 선언할 수 있다


UPROPERTY(EditAnywhere) : 언리얼 에디터에 속성이 노출되어 값을 설정할 수 있다(블루프린트의 '인스턴스 편집' 설정과 같은 개념)

UPROPERTY(BlueprintReadWrite) : C++ 함수를 블루프린트에서 Set, Get 노드를 사용하여 값을 읽거나 변경할 수 있다


함수 파라미터에 사용되는 UPARAM(ref) 도 있는데, UFUNCTION(BlueprintCallable)으로 지정한 함수의 파라미터 중에서 참조형으로 선언된 파라미터는 블루프린트에서 출력값(리턴핀)으로 나타나도록 되어 있다. 그러므로 함수 파라미터를 참조형으로 선언하려면 파라미터 자료형 왼쪽에 UPARAM(ref)를 추가로 선언해주어야 한다


위와 같이 코드상에서 설정하면 블루프린트에서 Construct Object from Class 노드를 사용하여 블루프린트에서 인스턴스를 생성하고 속성과 함수를 사용할 수가 있다. 또한 C++ 클래스를 기반으로 블루프린트 클래스를 생성하여 사용할 수도 있는데, 언리얼에서 해당 C++ 클래스 위에서 마우스 우측을 누르고 [MyObject 기반 블루프린트 클래스 생성] 을 선택하면 블루프린트 클래스가 별도로 생성되므로  Construct Object from Class 노드를 사용하여 인스턴스를 생성하고 사용할 수가 있다


언리얼 기반에서 어떤 클래스를 기반으로 하위 클래스를 파생할 것인가?

Plain Old C++ Object : 객체의 생성부터 소멸까지 개발자가 모두 관리하려는 경우

UObject : Garbage Collection, Network Marshalling, Serialization이 요구될 때

 - ConstructObject 를 이용한 객체 생성: 객체의 초기화의 모든 절차를 자동화함

 - NewObject 를 이용한 객체 생성: 객체의 초기화를 개발자가 직접 하는 경우

 - https://docs.unrealengine.com/en-us/Programming/UnrealArchitecture/Objects

AActor : 레벨 위에 보여져야 하는 경우, 월드 아웃라이너를 통해 관리하려는 경우

 - CPP 클래스를 작성하여 Actor 를 정의했더라도 액터에 다른 컴포넌트를 추가하려면 작성된 CPP 클래스를 기반으로 블루프린트 클래스를 생성하여 보다 편리하고 빠르게 작업을 할 수가 있다

 - http://api.unrealengine.com/INT/API/Runtime/Engine/GameFramework/AActor/index.html

APawn : AI Controller나 플레이어에 의해 조종되어야 할 액터

 - https://docs.unrealengine.com/en-us/Gameplay/Framework/Pawn

ACharacter : 두발로 걸어야 하는 액터

 - https://docs.unrealengine.com/en-us/Gameplay/Framework/Pawn/Character


언리얼엔진 기반의 C++클래스 작성시 위의 클래스를 상속해야 하는 경우가 대부분이며 다른 부모 클래스를 기반으로 하위 클래스를 파생하는 것도 물론 가능하다



C++ 프로젝트를 생성한다


Content Browser 에서 마우스 우측 > 새 C++ 클래스 > 부모 클래스 선택 창에서 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 "MyObject.generated.h"


/**

 *

 */

UCLASS(Blueprintable, BlueprintType)

class BP_CPP_API UMyObject : public UObject

{

GENERATED_BODY() // 내부에서 private 설정함

public:


UMyObject() {};


UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="MyObject")

FString message;


UFUNCTION(BlueprintCallable, Category="MyObject")

void SetMessage(FString msg);

};



소스파일 (적색으로 표시된 부분은 추가된 내용)

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


#include "MyObject.h"


void UMyObject::SetMessage(FString msg)

{

this->message = msg;

}


Visual Studio에서 위와 같이 편집한 후에 저장하고 다시 언리얼 에디터의 툴바에서 [컴파일] 버튼을 눌러서 컴파일을 완료한다


블루프린트에서 다음과 같이 MyObject 클래스의 인스턴스를 생성하고 사용할 수가 있다



C++ Object 파생클래스를 기반으로 블루프린트 클래스를 생성하여 블루프린트 클래스를 사용하는 절차


위와 같은 방법으로 C++에서 Object 파생 클래스를 작성했다면 언리얼 Content Browser의 C++ 클래스 위에서 마우스 우측 > [MyObject를 기반으로 블루프린트 클래스 생성]을 선택하면 블루프린트 클래스를 생성할 수가 있다. 



C++ 클래스 UObject 를 기반으로 생성한 블루프린트 클래스는 블루프린트에서 위와 동일하게 Construct Object from Class 노드를 사용하여 인스턴스를 생성하고 사용할 수가 있다


Posted by cwisky
Unreal C++/Custom Actor2017. 11. 23. 21:04

C++으로 작성한 커스텀 액터 클래스를 블루프린트에서 사용하기


Actor 클래스를 상속하여 C++에서 커스텀 액터 클래스를 생성하면 블루프린트에서는 SpawnActorFromClass 노드를 사용하여 일반 블루프린트로 만든 액터와 다를 바 없이 생성하여 사용할 수가 있다


언리얼 엔진을 실행하고 C++ 프로젝트를 생성한다


Content Browser 에서 마우스 우측 > 새 C++ 클래스 > 부모 클래스 선택 창에서 Actor 를 선택하고 [다음] 버튼을 누른다


파일 저장 경로를 선택하는 창에서 [클래스 생성] 버튼을 누르면 클래스가 생성되어 언리얼에 컴파일 되고 이어서 Visual Studio 가 실행되면서 생성된 클래스 헤더파일과 소스파일이 편집가능한 상태가 된다


필요한 속성이나 함수를 추가하고 정의한다


헤더파일과 소스파일을 저장하고 다시 언리얼 에디터의 툴바에서 [컴파일] 버튼을 눌러 컴파일한다


블루프린트에서 Spawn Actor from Class 노드를 추가하고 Class 핀에 커스텀 액터클래스의 이름을 지정하면 된다. 블루프린트에서 작성한 블루프린트 Actor 클래스를 사용하는 방법과 다를 바가 없다


생성된 C++액터클래스의 헤더파일 (적색으로 표시한 내용은 추가된 부분임)

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


#pragma once


#include "CoreMinimal.h"

#include "GameFramework/Actor.h"

#include "MyActor.generated.h"


UCLASS()

class BP_CPP_API AMyActor : public AActor

{

GENERATED_BODY()

public:

// Sets default values for this actor's properties

AMyActor();


protected:

// Called when the game starts or when spawned

virtual void BeginPlay() override;


public:

// Called every frame

virtual void Tick(float DeltaTime) override;


UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="MyActor")

FString message;


UFUNCTION(BlueprintCallable, Category="MyActor")

void SetMessage(FString msg);


};



생성된 C++ 액터클래스의 소스파일(적색으로 표시한 내용은 추가된 부분임)

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


#include "MyActor.h"



// Sets default values

AMyActor::AMyActor()

{

  // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.

PrimaryActorTick.bCanEverTick = true;


}


// Called when the game starts or when spawned

void AMyActor::BeginPlay()

{

Super::BeginPlay();

}


// Called every frame

void AMyActor::Tick(float DeltaTime)

{

Super::Tick(DeltaTime);


}


void AMyActor::SetMessage(FString msg)

{

this->message = msg;

}



블루프린트에서 C++ 커스텀 액터를 생성(Spawn)하고 사용하는 예



Posted by cwisky