<1>. 언리얼 콘텐츠의 구성 요소
<1> - 1. 월드 : 게임 콘텐츠를 구동하기 위해 필요한 필수적인 환경을 의미한다.
ex) 공간, 시간, 물리 법칙, 렌더링...
<1> - 2. 액터 : 콘텐츠를 구성하는 최소 단위의 물체 / '배우'처럼 자신의 역할을 수행하는 오브젝트.
※구성요소
- 이름
- 유형 : 액터의 역할 / 액터의 클래스 이름
- 트랜스폼
- 프로퍼티 : 액터에 설정된 속성 값.
- 게임 로직 : 코드
<1> - 3. 레벨 : 스테이지
<1> - 4. 컴포넌트 : 액터가 가질 수 있는 다양한 기능들을 규격화한 것.
- 스태틱메시 컴포넌트 : 애니메이션이 없는 모델링 에셋 / 시각적, 물리적 기능 제공.
- 스켈레탈메시 컴포넌트 : 애니메이션이 있는 모델링 에셋 / 시각적, 물리적 기능과 애니메이션 제공.
- 콜리전 컴포넌트 : 구/박스/캡슐로 지정한 영역에 물리적인 기능을 설정 / 시각적 기능은 없음.
- 카메라 컴포넌트 : 월드에서 보이는 상황을 모니터로 보여주는 기능.
- 오디오 컴포넌트 : 소리를 발생시키는 기능.
- 파티클 시스템 컴포넌트 : 파티클 시스템으로 설계된 이펙트를 보여주는 기능.
- 라이트 컴포넌트 : 물체에 광원 효과를 부여하는 기능.
- 무브먼트 컴포넌트 : 움직임을 부여하는 기능.
액터는 여러 개의 컴포넌트를 가질 수 있으며,
그중에서 대표하는 하나의 컴포넌트를 반드시 지정해야 한다. 이를 루트 컴포넌트 라고 한다.
왜냐하면 액터의 트랜스폼, 물리 처리 등 기반을 잡고 있을 컴포넌트가 하나 있어야 효율적이기 때문!
<2>. 액터의 설계 - 물이 흐르는 분수대 액터 만들기
분수대가 필요하고 물이 필요하다. 둘은 스테틱메시 컴포넌트인 것을 알 수 있다.
→ 분수대 액터의 멤버 변수로 2개의 UStaticMeshComponent 클래스의 포인터를 선언해줘야 한다.
(헤더파일의 'CoreMinimal.h'를 'EngineMinimal.h'로 변경해 줘야 클래스 정보를 참조할 수 있다.)
UStaticMeshComponent* Body;
UStaticMeshComponent* Water;
→포인터를 선언 → 메모리 동적 할당 → 명시적으로 객체를 소멸시켜야 차후 메모리 관리 문제 안 생김
→ 'UPROPERTY()' 매크로 사용하면 객체 자동 관리 가능.
UPROPERTY()
UStaticMeshComponent* Body;
UPROPERTY()
UStaticMeshComponent* Water;
액터의 구축은 클래스의 생성자 코드(Fountain.cpp)에서 진행된다.
생성자 코드에서 컴포넌트를 생성하는 함수는 'CreateDefaultSubobject'이다.
Body = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("BODY"));
Water = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("WATER"));
※ "BODY", "WATER" 같은 문자열은 액터에 속한 컴포넌트를 구별하기 위한 Hash값 생성에 사용된다.
이제 루트 컴포넌트를 지정해야 한다. (SetupAttachment)
RootComponent = Body;
Water->SetupAttachment(Body);
! 주의!책 예제에서는 이렇게만 해도 에디터에서 Body, Water를 확인할 수 있지만, 실제로는 루트컴포넌트인 Body만 보인다. UPROPERTY() 함수에 'VisibleAnywhere'을 해줘야만 Water까지 보인다.
<3>. 액터와 에디터 연동
두 스태틱메시 컴포넌트가 생성됐으니, 에디터에서 속성 값을 편집해 보자. (VisibleAnywhere)
루트 컴포넌트인 Body에 분수대 에셋을 넣고, Water에 물 에셋을 넣는다.
<4>. 액터 기능의 확장
그냥 Water에 물 에셋을 넣으면, 위치가 이상하다. Water 컴포넌트의 위치의 기본값을 설정하는 방법을 알아보자.
→ 'SetRelativeLocation' 함수를 이용하면 컴포넌트의 기본 위치 값을 변경할 수 있다.
→ 위치 값은 구조체 'FVector'를 사용해 표현한다.
Water->SetRelativeLocation(FVector(0.0f, 0.0f, 135.0f));
<5>. 에셋의 지정
여태까진 Fountain 액터의 컴포넌트에 에셋을 넣는 거였지만, 이제는 아예 Body 컴포넌트에 스태틱메시 에셋을 불러들여 설정 코드를 구현해 보자.
→ '레퍼런스 복사'를 통해 경로를 불러온다.
→ 이제 경로를 통해 에셋을 불러와야 한다. 'ConstructorHelpers' 클래스, 'FObjectFinder' 클래스를 사용한다.
→ 에셋의 경로 정보는 바뀔 일이 없으니 static으로 선언을 해주자.
static ConstructorHelpers::FObjectFinder<UStaticMesh>
SM_BODY(TEXT("/Game/InfinityBladeGrassLands/Environments/Plains/Env_Plains_Ruins/StaticMesh/SM_Plains_Castle_Fountain_01.SM_Plains_Castle_Fountain_01"));
if (SM_BODY.Succeeded())
{
Body->SetStaticMesh(SM_BODY.Object);
}
'게임 개발 > 이득우의 언리얼 C++' 카테고리의 다른 글
[이득우의 언리얼 C++ 게임개발의 정석] #7. 애니메이션 시스템의 설계 (0) | 2024.06.17 |
---|---|
[이득우의 언리얼 C++ 게임개발의 정석] #6. 캐릭터의 제작과 컨트롤 (0) | 2024.06.13 |
[이득우의 언리얼 C++ 게임개발의 정석] #5. 폰의 제작과 조작 (0) | 2024.06.10 |
[이득우의 언리얼 C++ 게임개발의 정석] #4. 게임플레이 프레임워크 (0) | 2024.06.10 |
[이득우의 언리얼 C++ 게임개발의 정석] #3. 움직이는 액터의 제작 (1) | 2024.06.08 |