기본
기본적으로 c++를 이용해 구현하고, 추가적으로 수정이 필요한 부분(AnimaionMontage와 같은 것들)은 해당 class 기반 blueprint를 통해 개발한다.
파일명을 지정할 땐 unreal convention에 따라 파일명 작성
- Blueprint = BP_NAME
- Skeletal Mesh = SK_NAME
- ...
새로운 클래스 추가시, 가급적 엔진 종료후 visual studio에서 컴파일 후 실행(오류자주생김)
Class
- PROJECTNAME_API 매크로의 경우 해당 클래스의 기능들을 다른 모듈에서 볼 수 있도록 함.
- 생성자에서 mesh, collision box 등을 설정.
- Tick과 BeginPlay는 부모 클래스에 있는 것들을 override 하므로 cpp파일에 Super::BeginPlay()와 같은 형식으로 사용.
Log
- UE_LOG(LogCategory, LogVerbosityLevel, __VA_ARGS__);
Log Verbosity Level의 종류
- Fatal
콘솔 및 로그 파일에 출력- Error
콘솔 및 로그 파일에 출력(빨간색)- Warning
콘솔 및 로그 파일에 출력(노란색)- Display
콘솔 및 로그 파일에 출력- Log
로그 파일에 출력- Verbose
로그 파일에 출력, 자세한 로깅 및 디버깅에 사용- VeryVerbose
로그 파일에 출력, 대량의 로그를 출력하는 상세한 로깅에 사용- GEngine->AddOnScreenDebugMessage();
(nullptr를 참조할 경우 충돌이 발생할 수 있으므로 반드시 체크후 사용)
언리얼에서 %s parameter를 사용하고 싶을 경우, *을 사용해야 함.(TChar 문자 배열)... if(GEngine) { FString Name = GetName(); FString Message = FString::Printf(TEXT("ItemName: %s, DeltaTime: %f), *Name, DeltaTime); GEngine->AddOnScreenDebugMessage(1, 3.f, FCollor::Blue, Message); } ...
- Blueprint에서 Log사용법
- OnScreen Debug Message
key값을 통해 메시지와 연결할 값을 지정 가능
key값이 같을 경우 이전 메시지를 새로운 메시지가 대체함(OnScreen2만 출력)
Macro
#define MACRO_NAME VALUE
를 이용하면 매크로 지정 가능
- 예시
* #define THIRTY 30 * #define DRAW_SPEHRE(Location) if(GetWorld()) DrawDebugsphere(GetWorld(), Location, 25.f, 24, FColor::Red, true);
UPROPERTY
변수에 UPROPERTY 매크로를 사용하여 Blueprint나 에디터에 해당 변수를 노출시킬 수 있다.
UPROPERTY()
- Details 패널 관련
- EditDefaultsOnly
Blueprint의 Details 패널에 있는 값 수정 가능- EditInstanceOnly
에디터 우측에 있는 Details 패널에 있는 값 수정 가능- EditAnywhere
Blueprint와 에디터 우측에 있는 Details 패널에 있는 값 수정 가능- VisibleDefaulstOnly
Blueprint의 Details 패널에 해당 값 노출만 가능, EventGraph에는 노출되지 않음- VisibleInstanceOnly
에디터 우측에 있는 Details 패널에 해당 값 노출만 가능, EventGraph에는 노출되지 않음- VisibleAnywhere
Blueprint와 에디터 우측에 있는 Details 패널에 해당 값 노출만 가능, EventGraph에는 노출되지 않음
- EventGraph 관련
- BlueprintReadOnly
Getter 함수와 같이 값을 읽기만 가능하도록 함- BlueprintReadWrite
Getter와 Setter함수와 같이 값을 읽고 설정하는것 둘다 가능하도록 함
- 기타
Category = "CATEGORY_NAME"
변수가 노출될 Category명 설정 가능
- meta = (AllowPrivateAccess = "true")
private 섹션에 변수가 있을 경우 Blueprint에서 변수사용이 불가능하다. 다른 곳을 제외한 Blueprint에서 값에 대한 수정을 원할 경우 사용하면 Blueprint에서 해당 변수를 사용가능하도록 한다.
UFUNCTION
함수에 UFUNCTION 매크로를 사용하여 Blueprint에 해당 함수를 노출시킬 수 있다.
- BlueprintCallable
Blueprint에서 함수호출이 가능하도록 함- BlueprintPure
c++ 클래스에서 매개변수를 받지 않아도 Blueprint에서 함수호출이 가능하도록 함(Blueprint에서 노드 추가시 노드 자체에서 값을 입력할 수 있음)
template
템플릿 함수 구현방법
1. 헤더파일에 템플릿 함수 선언template<typename T> T Avg(T First, T Second);
- 헤더파일에 템플릿 함수 구현
template<typename T> inline T AItem::Avg(T First, T Second) { return (First + Second) / 2; }
inline 함수이므로 컴파일시 해당 부분이 위 구현부로 대체됨.
Components
구성요소
Item class의 구성요소로써, Collision을 위한 BoxComponent, 외형 출력을 위한 MeshComponent 등이 있다.
GameMode
GameMode는 게임의 규칙과 동작을 정의하는 중요한 클래스이다.
주요 규칙, 라운드 진행, 스코어 보드 및 게임 종료 조건과 같은 기능을 제어가능하게 한다.
게임 초기화 및 시작, 플레이어 관리 등을 가능하게 함으로써 게임에 중요한 역할을 한다.
1. 하단의 Content Browser에서 GameModeBase Blueprint class를 생성한다.
2. 우측의 Details 패널에서 DefaultPawnClass를 사전에 생성해둔 Pawn Blueprint Class로 변경한다.
3. 에디터의 우측에 World Settings의 GameMode Override에 방금 생성한 GameMode Bluepirnt class를 적용시킨다.
위의 과정을 거친다면 오픈월드에서 나눠진 구역을 넘어갈 때 pawn이 증발하는 것을 방지할 수 있다(구역을 벗어나면 pawn의 소유권이 사라지지만, GameMode자체에서 Pawn의 소유권을 가지게 된다면 사라지지 않음).
RootBone(Blender)
Mixamo에서 필요한 에셋들을 다운받는 기준으로 서술(13.130).
예시로 사용할 캐릭터.
우선 Idle 애니메이션을 다운 받는데
첫번째로 다운받는idle 에셋
만With Skin
상태로 다운로드한다.
피격시 오른쪽으로 비틀거리는 애니메이션
피격시 뒤로 비틀거리는 애니메이션
피격시 왼쪽으로 비틀거리는 애니메이션
피격시 앞으로 비틀거리는 애니메이션 모두Without Skin
으로 다운로드한다.
Root Bone
이 없는 애니메이션이므로 따로 폴더를 만들어 저장해준다.
구글에Blender
를 검색후 설치한다(https://www.blender.org/).
필요한 플러그인을 깃허브에서 다운로드한다(https://github.com/enziop/mixamo_converter).
Blender에서 좌측 상단의Edit
->Preferences
로 들어가서 위쪽의Install
을 클릭한다.
방금 깃허브에서 설치한 플러그인을 선택하고Install Add-on
을 클릭한다.
마지막으로Animation: Mixamo Converter
에 체크표시까지 하면 플러그인 추가는 끝이다.
Preferences
창을 닫고 블렌더의 우측에 보면 xyz축 옆에 작은 화살표가 있는데
누르면 Mixamo 관련한 수정이 가능하다(보이지 않을 경우, Blender 재실행).
Input에 Rootbone이 없는 애니메이션의 경로를 입력하고, Output에 루트본이 생성된 애니메이션을 저장할 경로를 입력하면 된다.
Advanced Options
를 누르고Fixes:
의Apply Rotation
의 체크해제, 위쪽의Transfer Rotation
을 눌러 회색빛으로 표시되게 한 후Batch Convert
를 누르면 Root Bone 생성이 완료된다.
언리얼엔진으로 돌아와서 해당 에셋이 있는 폴더로 들어가면 Material을 제외한 나머지 파일들(PA, SK, SKM파일들)은RootBone
이 없는 상태이므로 전부 강제제거한다.
그리고 방금 Blender를 통해 RootBone과 Paladin 스킨이 있는 애니메이션을import
하면 RootBone이 있는 PA, SK, SKM파일들이 생성된다.
따로 폴더를 만들어 저장해둔 Material들을 적용시킨다.
필요없는Paladin_MAT
파일은 삭제하고 파일명을 적절히 rename해준다.
Animation을 따로 저장할 폴더를 생성해Idle
애니메이션 파일을 옮기고
다운로드한 다른 애니메이션(RootBone 추가된 파일들)도import
해준다.
이때import
할 애니메이션들은Without Skin
상태로 다운로드한 파일들이므로, 반드시 Skeleton에SK_Paladin
을 적용시켜주어야 하고,Import Mesh
는 체크해제한 상태로import
해야 한다.
import
한 애니메이션 파일들도 적절하게rename
해주면 끝.
Const Reference
parameter
에 const Reference를 이용한다면 parameter로 상수 호출이 가능하므로 효율을 높일 수 있다.// 예시1 int Add(int& num1, int& num2) { return num1 + num2; } int main(void) { int num1 = 10; int num2 = 20; std::cout << Add(num1, num2) << std::endl; return 0; } // 예시2 int Add(const int& num1, const int& num2) { return num1 + num2; } int main(void) { std::cout << Add(10, 20) << std::endl; return 0; }
Module 추가
몇몇 헤더파일을 사용하려면
PROJECT_NAME.Build.cs
파일에 모듈을 추가해주어야 한다.
API에 있는 필요한 모듈을 추가해주어야 한다.
파일을 열고 추가해준 뒤
경로에 있는Binaries
,Intermediate
,Saved
파일을 제거 한 후프로젝트 파일 우클릭
->Generate Visual Studio project files
클릭.
Casting
Casting
Casting은 특정 클래스의 액터를 취하여 다른 클래스인 것처럼 취급하려고 시도하는 작업이다. 캐스팅은 성공하거나 실패할 수 있다. 캐스팅에 성공하면 캐스팅 대상 액터의 클래스별 기능에 액세스할 수 있다.
예를 들어, 플레이어 캐릭터에 다양한 방식으로 영향을 줄 수 있는 여러 유형의 볼륨이 있는 게임을 만들고 있다고 가정해보자. 이러한 볼륨 중 하나는 시간이 지남에 따라 플레이어의 HP를 감소시키는 Fire이다. 플레이어가 레벨의 볼륨과 겹치면 해당 볼륨을 Fire에 캐스트 하여 "플레이어 HP 감소" 기능에 액세스하려고 시도할 수 있다.
캐스트가 성공하면, 즉 플레이어가 불 속에 서 있으면 플레이어의 HP는 감소한다.
캐스트가 실패하면, 즉 플레이어가 다른 종류의 볼륨에 서 있으면 플레이어의 HP는 감소하지 않는다.
생성<타입>(this, 타입)
예제코드
UPROPERTY() TObjectPtr<UOverlayWidgetController> OverlayWidgetController; UPROPERTY(EditAnywhere) TSubclassOf<UOverlayWidgetController> OverlayWidgetControllerClass; OverlayWidgetController = NewObject<UOverlayWidgetController>(this, OverlayWidgetControllerClass);
- ()의 첫번째 파라미터는 outer를 의미하는데, this를 통해 UOverlayWidgetController의 outer로 설정하여 객체 소유권 및 생명주기 관리.
- <>에 타입을 작성하고 ()안에 파라미터로 타입을 또 작성하는 이유는
- <>를 통해 생성할 기본 타입을 컴파일 단계에서 명확하게 하는 것이고
- 블루프린트에서 OverlayWidgetControllerClass를 지정해줌으로써 런타임에 동적으로 객체 생성이 가능하게 함
- 결론
타입 안전성:
템플릿 매개변수<UOverlayWidgetController>
는 생성할 객체의 기본 타입을 컴파일 시에 명확히 하는 기능
이를 통해 생성된 객체가 최소한 UOverlayWidgetController 타입임을 보장함
런타임 유연성:
OverlayWidgetControllerClass 파라미터를 통해 런타임에 객체의 서브클래스를 지정 가능하고
이를 통해 다양한 서브클래스를 동적으로 생성할 수 있는 유연성을 제공함
정적 타입과 동적 타입의 분리:
템플릿 매개변수는 정적으로 타입을 지정하고, 파라미터는 동적으로 서브클래스를 지정하는 역할을 하는데, 이 분리를 통해 코드의 유연성과 타입 안전성을 동시에 유지 가능
Delegate
함수를 대신해서 호출하는 역할
예제코드// 동적 멀티캐스트 델리게이트의 예시 // 인자로 델리게이트명, 파라미터타입, 파라미터명을 받음 DELCARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(DelegateName, ParamType, ParamName);
범위기반for문
예제코드
int NumArray[] = {0, 1, 2, 3, 4, 5}; // NumArray의 0번째 요소부터 Number에 할당되고 반복문을 통해 출력 for(int Number : NumArray) { cout << number << endl; }