언리얼 C++ 25.02.11

HyeonjungYun·2025년 2월 11일

언리얼 기초

목록 보기
16/23

BoxComponent

GetScaleBoxExtent()

UBoxComponent* Box = CreateDefaultSubobject<UBoxComponent>(TEXT("SpawningBox"));
FVector BoxExtent = Box->GetScaledBoxExtent();

박스 컴포넌트의 크기를 가져올 때 사용한다.
박스 컴포넌트의 중심부터 끝까지의 길이를 가져온다. 예를 들어 박스의 x y z의 길이가 (400, 100, 30)이고 박스의 Scale이 (2, 1, 1)일 때 GetScaleBoxExtent()함수가 가져오는 박스의 길이는 (800, 100, 30)이다.
박스의 Scale까지 고려해서 박스 컴포넌트의 크기를 가져온다.

GetComponentLocation()

UBoxComponent* Box = CreateDefaultSubobject<UBoxComponent>(TEXT("SpawningBox"));
FVector BoxOrigin = Box->GetComponentLocation();

박스의 위치를 리턴한다. 여기서 박스의 위치는 박스의 중심값이다.

TSubclassOf<T>, TSoftClassPtr

TSubclassOf<T>

AActor* Function(TSubclassOf<AActor> ItemClass)
{
}

클래스가 항상 메모리에 로드된 상태에서 바로 접근하는 하드 레퍼런스를 의미한다.

위의 코드에서 TSubclassOf<AActor> ItemClass는 AActor클래스의 하위 클래스들을 모두 포함하게 된다.

TSoftClassPtr

TSubclassOf<T>와 다른 소프트 레퍼런스로 포인터로 클래스의 경로만을 저장하여 저장된 클래스에 접근한다.

-> 두 가지 모두 클래스를 참조하기 위한 데이터 구조이다.

Data Table


언리얼 엔진에선 데이터들을 저장할 수 있는 Data Table를 지원한다.
콘텐츠 브라우저에서 우클릭하여 Miscellaneous에서 Data Table을 선택하면 Data Table이 생성할 수 있다.


여기서 저장할 데이터의 행이 되는 데이터 구조체를 선택한다.


그리고 여기서 행을 추가하여 데이터를 저장할 수 있다.

Data Table의 데이터 구조체 만드는 법

Data Table에 사용될 데이터 구조체를 만들기 위해선 우선 C++클래스를 만들어야 한다. 하지만 실제 클래스가 아닌 "구조체"를 만들것이기 때문에 아무것도 상속되지 않은 None 클래스를 생성한다.

#pragma once

#include "CoreMinimal.h"

USTRUCT(BlueprintType)
struct FDataTableRow : public FTableRowBase
{
public:
	// 구조체에 추가할 정보 예시
    UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FName ItemName;
};

그리고 만든 클래스의 헤더파일을 위의 코드처럼 바꾸어주어야 한다.
Data Table에서 사용할 것이기 때문에 FTableRowBase을 상속받아야 한다.

USTRUCT(BlueprintType)를 사용하여 내가 만든 구조체를 리플렉션 시스템에 등록하게 되고, 블루프린트에서 변수로써 다룰 수 있게된다.

구조체에 담을 정보들도 블루프린트 내에서 다룰 수 있어야 하기에 UPROPERTY로 리플렉션 시스템에 등록해주어야 한다.

데이터 테이블 변수 선언

UDataTable* DataTable;

데이터 테이블 변수 선언은 이런 식으로 하면 된다.

GetAllRows()

TArray<FDataTableRow*> AllRows;
static const FString ContextString(TEXT("DataTableContext"));

DataTable->GetAllRows(ContextString, AllRows);

데이터 테이블에서 모든 행을 가져오려면 GetAllRows함수를 사용하여 데이터 테이블의 모든 행들을 가져올 수 있다.
여기서 GetAllRows함수를 사용할 땐 두 개의 매개변수가 필요하다.
FString과 모든 행들을 저장할 TArray<T>가 필요한데, 여기서 FString은 데이터 테이블에서 행을 가져올 때 디버깅 정보를 제공하는데에 사용된다. 데이터 테이블에서 오류가 발생했을 때 이 FString이 오류 메시지에 포함되어서 문제를 추적할 때 도움이 된다.

UGameplayStatics::ApplyDamage, AActor::TakeDamage

액터가 데미지를 입고 입히게 하는 로직이다.

UGameplayStatics::ApplyDamage함수로 특정 액터에 데미지 받았다는 신호를 보내면 해당 액터의 TakeDamage함수가 작동하여 해당 액터가 어떤 액터에게 얼마만큼의 데미지를 받았는지를 받아서 함수를 작동시킨다.

UGameplayStatics::ApplyDamage

static float ApplyDamage(
    AActor* DamagedActor,
    float BaseDamage,
    AController* EventInstigator,
    AActor* DamageCauser,
    TSubclassOf<class UDamageType> DamageTypeClass
);

DamagedActor : 데미지를 받을 액터입니다. 이 액터는 TakeDamage를 호출하여 데미지를 처리합니다.
BaseDamage : 가하는 기본 데미지 양입니다. TakeDamage에서 이 값을 기반으로 최종 데미지를 계산할 수 있습니다.
EventInstigator : 데미지를 가한 캐릭터의 컨트롤러입니다. (예: 플레이어 캐릭터 또는 AI 컨트롤러)
DamageCauser : 데미지를 유발한 오브젝트입니다. 예를 들어, 발사체, 폭발 또는 근접 무기가 될 수 있습니다.
DamageTypeClass : 데미지 유형을 지정합니다. 기본 데미지 유형은 UDamageType이며, 사용자 정의 데미지 유형을 상속하여 확장할 수 있습니다.

AActor::TakeDamage

virtual float AActor::TakeDamage(
	float DamageAmount, 
	FDamageEvent const& DamageEvent, 
	AController* EventInstigator, 
	AActor* DamageCauser) override;

DamageAmount : 가한 데미지의 양
DamageEvent : 데미지 유형 및 추가 정보를 담고 있는 구조체
EventInstigator : 데미지를 유발한 캐릭터를 제어하는 컨트롤러
DamageCauser : 데미지를 가한 원본 액터 (예: 폭발을 유발한 무기 등).

GameState, PlayerState

캐릭터의 체력 및 점수와 같은 캐릭터의 고유 정보들은 보통 PlayerState에 저장한다. PlayerState는 동기화와 관련된 기능들을 제공하기 때문에 멀티 플레이 게임에선 반드시 캐릭터의 정보를 저장할 땐 PlayerState에 저장하지만 싱글 플레이 게임에선 굳이 PlayerState에 정보들을 저장하지 않아도 된다.

GameState : 전역 정보를 저장하는 곳(맵에 스폰된 아이템의 갯수, 진행도, 게임 시작 후 몇 초가 지났는지 등등)
PlayerState : 플레이어 마다의 고유한 정보를 저장

GameState와 Gamemode는 긴밀하게 연동될 수 있도록 설계가 되어 있는데, GameState Base는 간소하게 설계되어 있어서 Gamemode와 GameState Base를 연결지어 사용하면 Gamemode의 기능들을 사용하지 못 하는 순간들이 올 수도 있다.

profile
게임 프로그래머 공부

0개의 댓글