액터의 구조
- 월드에 속한 콘텐츠의 기본 단위를 액터라고 함.
- 액터는 트랜스폼을 가지며, 월드로부터 틱과 시간 서비스를 제공받는다.
- 액터는 논리적 개념일 뿐 컴포넌트를 감싸는 포장 박스에 불과.
- 실질적인 구현은 컴포넌트가 진행하고 액터는 다수의 컴포넌트를 소유하고 있음.
- 다수의 컴포넌트를 대표하는 컴포넌트를 루트 컴포넌트(Root Component)라고 한다.
- 액터는 루트 컴포넌트를 가져야 하며, 루트 컴포넌트의 트랜스폼은 액터의 트랜스폼을 의미
C++ 액터에서 컴포넌트 생성
- 컴포넌트는 언리얼 오브젝트이므로 UPROPERTY를 설정하고 TObjectPtr로 포인터를 선언
- 언리얼 5버젼부터 헤더에 언리얼 오브젝트를 선언할 때 일반 포인터에서 TObjectPtr로 변경
- 컴포넌트의 등록
- CDO에서 생성한 컴포넌트는 자동으로 월드에 등록된다.
- NewObject로 생성한 컴포넌트는 반드시 등록절차를 거쳐야 한다. ( 예) RegisterComponent)
- 등록된 컴포넌트는 월드의 기능을 사용할 수 있으며, 물리와 렌더링 처리에 합류한다.
- 컴포넌트의 확장 설계
- 에디터 편집 및 블루프린트로의 승계를 위한 설정
- UPROPERTY에 지정자(Specifier)를 설정할 수 있다.
- 컴포넌트 지정자
- Visible / Edit : 크게 객체타입과 값타입으로 사용
- Anywhere / DefaulsOnly / InstanceOnly : 에디터에서 편집 가능 영역
- BlueprintReadOnly / BlueprintReadWrite : 블루프린트로 확장시 읽기 혹은 읽기쓰기 권한을 부여
- Category : 에디터 편집 영역(Detail)에서의 카테고리 지정.
분수대 제작을 통한 실습
BluePrint로 생성된 분수대를 최소한의 BluePrint만 이용하고 나머지를 C++로 정의함.
1. BluePrint Actor 생성
- BluePrint 생성
- Static Mesh 생성
2. C++ 분수대 생성
- Class 생성
- Header
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "ABFountain.generated.h"
UCLASS()
class ARENABATTLE_API AABFountain : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AABFountain();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Body 생성
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category=Mesh)
TObjectPtr<class UStaticMesh> Body;
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = Mesh)
TObjectPtr<class UStaticMesh> Water;
};
VisibleAnyWhere : 에디터 편집 가능 영역
BlueprintReadWrite : 블루프린터로 읽고 쓰기 가능
Category=Mesh : Mesh에 대한 카테고리에 Body 값을 편집할 수 있게 에디터 UI 제공
- cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Prop/ABFountain.h"
#include "Components/StaticMeshComponent.h"
// Sets default values
AABFountain::AABFountain()
{
// 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;
// Body와 Water의 오브젝트 설정
Body = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Body"));
Water = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Water"));
// RootComponent의 지정
RootComponent = Body;
// Body의 자식으로 설정
Water->SetupAttachment(Body);
Water->SetRelativeLocation(FVector(0.0f, 0.0f, 132.0f));
// Static Mesh 지정
static ConstructorHelpers::FObjectFinder<UStaticMesh> BodyMeshRef(TEXT("/Script/Engine.StaticMesh'/Game/ArenaBattle/Environment/Props/SM_Plains_Castle_Fountain_01.SM_Plains_Castle_Fountain_01'"));
if (BodyMeshRef.Object)
{
Body->SetStaticMesh(BodyMeshRef.Object);
}
static ConstructorHelpers::FObjectFinder<UStaticMesh> WaterMeshRef(TEXT("/Script/Engine.StaticMesh'/Game/ArenaBattle/Environment/Props/SM_Plains_Castle_Fountain_01.SM_Plains_Castle_Fountain_02'"));
if (WaterMeshRef.Object)
{
Water->SetStaticMesh(WaterMeshRef.Object);
}
}
//... 생략
BodyMeshRef 와 WaterMeshRef에 들어가는 참조 경로는
Environments에서 Mesh의 CopyReference를 통해 경로를 참조
이후 컴파일을 통한 Actor 생성
3. C++을 이용한 액터 생성
ABFountain이라는 Actor가 생성된 모습
4. 기존 BluePrint의 Parent Class 변경
ParentClass로 받고 기존의 Body와 Water만 제거
5. 실습의 의의
이렇게 만들어진 분수대 블루프린트의 경우는 앞의 제작과 동일하지만 C++로 기반을 충분히 다져 놓고 추가적인 로직은 블루프린트로 필요한 만큼만 최소 한도로 확장하도록 설계하는 것이 게임 제작을 효과적으로 제작 가능.
6. 참조
다음 강의를 수강하고 작성한 글입니다.
'Unreal' 카테고리의 다른 글
UE C++ 리플렉션 (0) | 2024.06.22 |
---|---|
UE 캐릭터 입력 시스템 (0) | 2024.06.15 |
UE C++ 빌드 시스템 (0) | 2024.06.01 |
UE C++ 직렬화 (0) | 2024.05.25 |
UE C++ 메모리 관리 (0) | 2024.05.19 |