공부/Unreal

24.07.04

월러비 2024. 7. 7. 15:36
  • 오브젝트 레퍼런스 : 객체와 같은, 즉 타입이 아닌 변수다.
  • 클래스 레퍼런스 : 클래스 타입을 받는다. (예를 들어, BP_Mesh를 받을때 BP_Mesh라는 ‘타입’을 받는다.)
    • 클래스 타입을 변수로 넣어 기본값에서 여러 클래스를 받을 수 있다.
  • 블프는 오버로딩을 허용하지 않아서 ‘이름이 같으면 같은 함수다’
    • 그래서, C와 블프의 함수 이름이 다른것이다.
  • 언리얼은 ‘루트 컴포넌트’의 경로를 ‘소스 폴더’로 맞추기 때문에 ../를 써야한다.
    • 굳이 안쓰도록 설정할 수 있다.
  • 소스 파일(cpp파일)에 작성한 include 코드는 전파가 되지 않는다.
    • 헤더 파일의 include는 전파가 된다.
    • 즉, Engine.h 같이 무거운 헤더를 cpp 파일에 작성하면 전파가 안되게 하기에 이렇게 사용하는 것이다.

클래스 타입 코드로 설정

  • 클래스 ‘타입’ 자료형은 T 접두사를 붙여서 사용한다.
    • TSubclassOf<클래스 타입>
    • 클래스 타입 사용 방법
      1. TSubclassOf<AC02_Mesh> ⇒ 이렇게 써도 되지만 이렇게 변수를 선언하면 헤더파일 include에 #include “C02_Mesh.h” 를 추가해줘야한다.
      2. cpp 파일에 #include “C02_Mesh.h”를 작성하면 다른곳으로 전파가 안되게 할 수 있다.
        1. 이렇게 사용하면 헤더파일에 TSubclassOf<class AC02_Mesh>를 해서 class를 붙여줘야한다. ⇒ 지금은 이렇게 사용한다.
        2. 이걸 ‘전방 선언’이라고 한다.
        3. 클래스를 또 쓰고싶다면 class를 계속 붙여줘야한다. (class AC02_Mesh* B;)
      3. 선언한 클래스를 다른곳에서도 사용한다면 include 윗줄에 class AC02_Mesh; 로 선언하면, 다른 곳에서는 AC02_Mesh* B;로 선언이 가능하다.
        1. 이 방법은 사용할 클래스가 많아지면 오히려 산만해지는 경우가 많다.
      • 2번과 3번을 번갈아가며 사용한다.

클래스 타입 코드로 스폰

  • 구조체는 다 ‘F’ 가 접두사로 붙는다.
    • FTransform : 블루프린트로 설명하자면, Transform 노드다.
  • UObject* 로 자료형을 지정하게 된다면, 모든 오브젝트가 표시된다.
  • UClass* 로 자료형을 지정하게 된다면, 모든 클래스가 표시된다.
    • 그래서, TSubclassOf<클래스 타입> 으로 클래스를 제한시켜서 표시시키는 것이다.
  • 변수 타입 가져오기
    • 헤더파일 - 매크로 타입과 카테고리 지정
    UPROPERTY(EditAnywhere, Category = "Settings")
    		TSubclassOf<class AC02_Mesh> SpawnClasses;
    
  • 레벨 에디터에 스폰시키기
    • cpp 파일 - 월드(레벨)을 전부 가져오고 액터를 스폰하는 함수를 호출한다.(배치할 클래스, 좌표 가 필요하다.) - 자신의 위치를 반환하는 함수를 ‘벡터 자료형’의 변수에 넣는다. - 배치할 좌표를 넣을 ‘트랜스폼 자료형’ 변수 생성 - 트랜스폼 변수에 위치 변수를 설정하는 함수를 호출한다. - 트램스폼 변수를 ‘액터 스폰’ 함수의 매개변수로 넣는다. - C++ 기반 블프 생성 - 블루프린트 파일 - 디테일 - 클래스 지정
    FVector location = GetActorLocation();
    
    //구조체는 F 접두사가 붙는다.
    FTransform transform;
    transform.SetLocation(location);
    
    //레벨에 배치된 액터를 가져온다.
    GetWorld()->SpawnActor<AC02_Mesh>(SpawnClasses, transform);
    

클래스 여러개 코드로 스폰

  • 클래스 타입 변수를 배열로 선언
    • 헤더 파일 - 클래스 타입 변수를 배열로 선언
    UPROPERTY(EditAnywhere, Category = "Settings")
    		TSubclassOf<class AC02_Mesh> SpawnClasses[3];
    
  • 배열 변수로 여러개 스폰시키기
    • cpp 파일 - 반복 시작 - 이전 코드 수정 - ‘액터 스폰’ 함수의 매개변수에 현재 순서의 값을 넣는다. - 현재 위치에서 Y값을 증가시켜서 순서대로 배치되도록 설정한다. - 블프 파일 - 디테일 - 배치할 클래스 지정
    for (int32 i = 0; i < 3; i++)
    	{
    		if (SpawnClasses[i] == nullptr)
    		{
    			continue;
    		}
    
    		FVector location = GetActorLocation();
    		location.Y += i * 350.0f; //0 350 700으로 배치된다.
    
    		//구조체는 F 접두사가 붙는다.
    		FTransform transform;
    		transform.SetLocation(location);
    
    		//레벨에 배치된 액터를 가져온다.
    		GetWorld()->SpawnActor<AC02_Mesh>(SpawnClasses[i], transform);
    	}
    

../ 안쓰고 기본 폴더 설정하기 - Module 폴더 경로 추가

  • 언리얼은 기본으로 Source 폴더를 기준으로 헤더를 탐색한다.
    • ../01_Spawn/C03_Spawner.h
    • 상속하면 파생 클래스에도 ../를 붙여줘야하기에 매우 번거롭다.
  • Build.cs 파일이 Alt + B + B 눌렀을때의 ‘빌드’를 설정하는 파일이다.
    • 여기에 PublicIncludePaths.Add(ModuleDirectory); 를 추가한다.
    • 이렇게 하면 ../ 를 붙이지 않아도 컴파일이 가능하다.
    • PublicIncludePaths.Add : include 경로를 하나 더 추가시켜주는 함수다.
    • ModuleDirectory : Source 폴더 내부의 ‘프로젝트 이름’ 폴더를 가리키는 경로다.
      • ‘프로젝트 이름.Build’ , ‘프로젝트 이름.cpp’, ‘프로젝트 이름.h’ 파일들이 있는 폴더를 ‘Modul 폴더’라고 한다. ⇒ C에서 흔히 ‘라이브러리’라고 부르는 폴더다. ⇒ 게임을 실행하는 주체 라고 생각해라
      • 원래는 Source 폴더를 기준으로 하지만 Source폴더 내부의 Module 폴더도 기준으로 만드는 코드다.

printstring 처럼 화면에 띄우는 기능 구현

  • 기능 구현에 도움이 되는 기능 : Utility
  • C++ 클래스에 표시되는 클래스들은 ‘UObject’ 이하로 상속받은 클래스들만 나타날 수 있다.
    • 부모가 없는 클래스들은 에디터상에 표시되지 않아서 비주얼 스튜디오에서 확인해야한다.
  • Engine.h : 언리얼 엔진의 헤더들을 모아놓은 헤더다.
    • 무척 큰 헤더다.
    • cpp 파일에 넣어서 딱 한번만 컴파일해서 모든 클래스에서 쓸 수 있게 해야한다.
  • static : 메모리 공용영역에 저장되는 자료형이다.
    • ‘객체’를 생성하지 않아도 ‘클래스 이름’으로 ‘함수’를 사용할 수 있게 된다.
      • CLog::Log(10);
  • 부모 클래스 없는 클래스 생성
    • C++ 클래스 폴더 - C++ 클래스 생성 - 부모 없음 - 새 폴더 생성 후 생성

 

  • 비주얼 스튜디오에서 새 클래스를 추가할 때 생성 경로를 주의해야한다.
    • 프로젝트 파일이 있는곳을 경로로 잡기 때문이다.
  • 프로젝트 파일 위치 : Intermeieate 폴더의 ProjectFiles 폴더
    • vcxproj 확장자의 파일이 프로젝트 파일이다.
    • .filters : 프로젝트 내부의 나눠져있는 폴더의 정보를 가지고 있는 파일이다.
  • 클래스가 갖고있는 기능과 함수를 알고싶다면 클래스를 ‘구글’에 검색해봐라
  • ‘구조체’ 자료형의 변수는 값 복사가 일어난다.
    • 속도 성능이 떨어진다.
    • 그래서, ‘레퍼런스’를 이용한다. (Fsting& ⇒ &을 말하는 것이다.)
      • 이렇게하면 함수에 넣을 변수를 초기화해도 함수에 레퍼런스로 들어온 매개변수의 정해진 값으로 출력된다.
  • 출력로그는 역순으로 출력된다.
    • 예를 들어, 회전값은 롤 ‘ 피치 ‘ 야 순서지만, 출력로그에 출력되는 순서는 야 ‘ 피치 ‘ 롤 순서다.
  • ‘U’ 가 붙은 클래스를 사용할때는 ‘* 포인터’를 사용한다.
    • Log(const UObject* InValue)
  • Unreal C++ 널 확인 연산자 : !!
    • C# 널 확인 연산자 : ?

02 예제, printstring 처럼 화면에 띄우는 기능 구현

  • 로그나 기록을 추적하는 기능 : Profiler (Log 기능 등)
  • 출력로그 - 경고 : Warning - 문제가 있을 수 있다.
  • 출력로그 - 오류 : 문제가 있다.
  • 출력로그 - 메세지 : 경고와 오류 모두 포함
    • 출력로그에서 ‘:’ 콜론 앞에 나오는것이 ‘카테고리’다.
    • 출력로그의 필터에서 카테고리를 지정해서 볼 수 있다.

모든 곳에서 사용하는 유틸리티 헤더 파일 생성

  • Module 폴더에 헤더파일 생성(비주얼 스튜디오 내에서 생성하면 헤더파일 만 생성할 수 있다.) - 유틸리티 폴더에 생성한 헤더를 모은다.
#pragma once

#include "Utilities/CLog.h"

Log 유틸리티 생성

  • static 함수 선언 - cpp 파일 - 선언한 함수 정의
//header
static void Log(int32 InValue);

//cpp
void CLog::Log(int32 InValue)
{
	//static이 붙은건 그냥 함수 이름으로 사용할 수 있다.
	GLog->Log(FString::FromInt(InValue));
}

유틸리티 사용

  • 글로벌(내가 작성한) 헤더 추가 - 함수 호출 - 기반 블프 파일 생성 - 레벨 에디터에 배치
//cpp
#include "Global.h"

CLog::Log(10);

출력로그 카테고리 생성

  • cpp 파일 - 헤더에서 생성한 함수에 ‘카테고리 명’, ‘출력 방식’ , ‘출력 내용’을 넣는다.
  • GLog->Log 는 ‘양식 문자열’을 사용하지 못하기 때문에 다른 방식으로 출력할 것이다.
//cpp
GLog->Log("Game", ELogVerbosity::Display, FString::FromInt(InValue));

카테고리 정의

  • cpp 파일에서 ‘UE_LOG’라는 매크로를 사용하기 위해서 카테고리를 정의해줘야한다.
    • 카테고리 명, 출력 방식- 컴파일 타임에서 보여줄지 ‘ 전체 다 보여줄지 여부
  • 출력하려는 값을 변하지 않게 하기 위해 ‘상수 const’로 정의할 수 있다.
  • cpp 파일 - 상단 정의
//cpp
DEFINE_LOG_CATEGORY_STATIC(Game, Display, All)

UE_LOG(Game, Display, L"%d", InValue);

Null 판단(!!) 및 조건 확인(?) 연산자 사용

  • cpp 파일 - 함수 정의
//cpp
void CLog::Log(const UObject * InValue)
{
	FString str;

	//C++ 널 확인 연산자 : !!
	if (!!InValue)
	{
		str.Append(InValue->GetName());
	}

	str.Append(!!InValue ? " Not Null" : "Null");

	UE_LOG(Game, Display, L"%s", *str);
}

02 예제, 레벨 에디터에 로그 출력

  • 파라미터 값을 받아서 쓸 변수는 ‘In’ 접두사(키워드)를 붙인다.
    • 나중에 ‘리턴’ 해야하는 변수는 ‘Out’ 접두사(키워드)를 붙인다.
  • 디폴트 파라미터는 ‘소스파일 cpp’가 아닌 ‘헤더파일’ 에서만 작성해야한다.
  • 헤더파일 - 함수 선언 - cpp 파일 - 함수 정의 - 함수 사용할 cpp 파일 - 함수 사용
//header
static void Print(int32 InValue, int32 InKey = -1, float InDuration = 10, FColor InColor = FColor::Blue);

//cpp
void CLog::Print(int32 InValue, int32 InKey, float InDuration, FColor InColor)
{
	//G는 글로벌(전역)으로 쓸 수 있는 것들이다.
	GEngine->AddOnScreenDebugMessage(InKey, InDuration, InColor, FString::FromInt(InValue));
}

//함수 사용
CLog::Print(10); //안쓴 매개변수는 디폴트 값이 들어간다.

C++ 함수 모음

  • TSubclassOf<클래스 타입> : 다른 클래스를 가리키는 UClass 포인터를 저장하며, 해당 클래스의 하위 클래스만을 가리킬 수 있다.
    • UClass 타입의 안전성을 보방해주는 템플릿 클래스다.
    • 블루프린트로 설명하자면, 변수 생성할때 ‘클래스 레퍼런스’로 설정하는것과 같은 기능이다.
    • 즉, 정리하자면 클래스 타입을 가진 클래스만 표시하도록 ‘클래스를 제한시켜서 표시’하는 자료형이다.
  • PrimaryActorTick.bCanEverTick = bool 타입 값 ⇒ 틱 이벤트를 실행시켜주는 함수다.
  • GetWorld() : 월드(레벨) 전체를 가져온다.
    • SpawnActor<스폰 시킬 타입(클래스 등)> : 블루프린트의 ‘SpawnActor NONE(from Class)’와 같은 역할을 하는 함수다.
  • GetActorLocation() : 자신의 위치를 반환하는 함수다.
  • GetActorRotation() : 자신의 회전값을 반환하는 함수다.
  • FTransform : 트랜스폼 자료형
    • SetLocation(위치 좌표) : 위치를 ‘위치 좌표’로 설정하는 함수다.
  • ELogVerbosity : 디버깅을 용이하게 만들어주는 ‘로깅’ 기능을 제공한다.
    • Fatal : .치명적인 문제를 찾아 반환하는 함수다.
    • Error : 코드에 빨간줄처럼 오류가 있다는것을 반환하는 함수다.
    • Warning : 코드에 문제가 있을것같다고 반환하는 함수다.
    • Display : 출력 로그와 Saved 폴더 안의 Log 파일에 메세지를 기록하는 함수다.
    • Log : Log 파일에만 기록하는 함수다.
  • GEngine : 엔진 관련 기능 모음
    • AddOnScreenDebugMessage(뭔지 모를 값, 지속 시간, 출력 색상, 출력 값) ; 레벨 에디터에 들어온 값을 출력하는 함수다.

블루프린트 함수 모음

  • SpawnActor NONE(from Class) : ‘지정된 클래스’의 액터를, ‘지정된 위치와 회전값’에 배치하는 함수다.
  • Get Actor Location : 액터의 위치 좌표를 가져온다. ⇒ 트랜스폼에 연결할때 구조체 분할을 한 다음 연결해야한다.
  • Make Transform : 트랜스폼 값을 반환하는 ‘구조체’ 노드다.
    • Get Actor Location - Make Transform을 트랜스폼 핀에 연결하는것이, Get Actor Location은 구조체 분할한 트랜스폼 핀에 연결하는것과 같은 기능을 한다.

'공부 > Unreal' 카테고리의 다른 글

24.07.11  (1) 2024.07.14
24.07.10  (1) 2024.07.12
24.07.03  (2) 2024.07.05
24.07.02  (1) 2024.07.03
24.07.01  (0) 2024.07.03