📕 CDO (Class Default Object) 에러
호출해야 하는 자료(Object)들이 존재하지 않아서 생기는 오류로, 컴파일이 완료된 후 hot reload 상황에서 발생하기 때문에 컴파일은 이미 완료 된 상태에서 에러가 난다.
주로 찾으려는 오브젝트의 경로를 잘못 작성했을 때 발생한다.
📗 무기 장착/해제 기능 구조
class Weapon
{
virtual void Equip()
{
if(장착 조건)
return;
}
}
class Rifle : Weapon
{
void Eqiup()
{
if(장착 조건) // 비효율적인 코드 작성!
{
Super::Equip();
}
}
}
무기의 최상의 클래스인 Weapon 클래스를 만들고, Weapon을 상속받는 각각의 종류별 무기(ex. Rifle)을 만든다고할 때, 무기를 장착하는 기능인 Equip() 함수를 생성할 것이다.
만약 부모클래스인 Weapon::Equip() 함수에서 무기 장착이 가능한지에 대한 조건문을 걸었다면, Weapon을 상속받은 자식클래스 Rifle에서도 똑같은 조건문을 걸고, 무기 장착이 가능한 경우에만 부모클래스의 Super::Equip() 함수를 사용할 수 있다.
이는 결국 똑같은 조건문을 작성하며 비효율적인 구조로 이루어지게 된다.
class Weapon
{
virtual void Equip()
{
if(장착 조건) return;
}
virtual bool CanEquip()
{
return 장착조건;
}
}
class Rifle : Weapon
{
void Eqiup()
{
if(Super::CanEquip()) // 혹은 Override 후 CanEquip();
Super::Equip();
}
}
이를 해결하기 위해 무기 장착이 가능한지를 체크해주는 CanEquip() 함수를 만들고 추가로 자식클래스에서 더 검사하고싶은 조건이 있다면 재정의하여 사용할 수 있도록 추상화 함수로 작성하는 방법이 있다.
📘 실제 적용 코드
설명한 구조대로 C++ 클래스인 Weapon을 작성한 내용이다.
나는 클래스 자체를 abstract로 추상화하여 Weapon을 상속받는 종류별 무기들이 함수를 호출하여 사용할 수 있도록 구현하였다.
📙 Abstract 지정자
클래스를 추상클래스로 지정했을 때의 효과는 언리얼 문서에 더 자세히 나와있다.
이는 C++의 추상화가 아닌, 언리얼만의 추상화이기 때문에 순수 가상함수가 꼭 존재하지 않아도 된다. 또한 추상은 상속되지 않는다.
또한 문서에 적힌 내용대로 만들어진 추상 클래스는 뷰포트에 드래그하여 배치할 수 없고, Weapon을 상속받아 구현한 Weapon_AR4만이 뷰포트에 드래그하여 배치할 수 있다.
Weapon의 기능을 제어할 WeaponComponent를 제작하고, 무기 종류에 따른 Enum값을 생성하였다.
일반적인 방법으로 Class 안에 enum Type { A, B}; 처럼 선언하는 것은 직렬화가 안되기 때문에 UENUM을 사용하여 직렬화해야 한다.
이때 주의할 점은 ENUM이나 STRUCT 전부 다 직렬화를 시키기 위해선 직렬화 코드를 UCLASS 위와 gernerated 헤더파일 아래인 그 사이에 위치해야 한다는 점이다.
📓 inline, FORCEINLINE
bool IsUnarmedMode() { return Type == EWeaponType::Max; }
위와 같이 작성된 코드를 inline 함수라고 한다.
inline 키워드는 inline, _inline, __inline 의 총 세 종류가 존재하는데, 컴파일러 설정에 따라 모두 다르게 적용된다.
프로그래머가 강제할건지, C 컴파일러가 강제할건지, 상황에따라 강제할건지가 모두 다르다. 또한 언리얼에서는 CPU 스펙마다 강제가 다르기때문에, FORCEINLINE 매크로를 붙여 무조건 인라인 함수가 되도록 강제시킬 수 있다.
FORCEINLINE bool IsUnarmedMode() { return Type == EWeaponType::Max; }
FORCEINLINE 는 간단한 Return 함수나 간단한 Set 함수 같은 경우는 Main으로 점프한 뒤 돌아올 필요없이 바로 실행시키면 되기때문에 무조건 inline을 사용하도록 만드는 매크로이다.
💡 FActorSpawnParameters
FActorSpawnParameters는 SpawnActor함수를 실행시킬 때 Spawn 관련 설정들을 전부 설정할 수 있는 자료형이다.
위 코드는 Weapon Component에서 Weapon을 Spawn 시킬 때 Owner를 플레이어(Owner)로 설정하고, 언제나 스폰되도록 AlwaysSpawn 설정을 저장한 내용이다.
💡 GetComponent
Get Component 기능을 템플릿화하여 편리하게 함수로 만들었다.
하나의 Component를 찾아올 때는 GetComponentByClass 함수를 사용하여 매개변수로 StaticClass 정보를 전달한다.
추가로 컴포넌트 이름을 전달했을 때 해당 이름인 컴포넌트를 반환해주는 함수도 작성하였는데, 이는 GetComponents 함수를 이용하여 InActor에 존재하는 모든 컴포넌트 정보를 불러오고, 그 컴포넌트들을 for문 돌면서 이름을 검사한다.
참조
클래스 지정자
클래스가 엔진과 에디터의 다양한 부분과 어떻게 작동하는지를 지정하기 위해 UClass 선언시 사용되는 키워드입니다.
docs.unrealengine.com