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까지 고려해서 박스 컴포넌트의 크기를 가져온다.
UBoxComponent* Box = CreateDefaultSubobject<UBoxComponent>(TEXT("SpawningBox"));
FVector BoxOrigin = Box->GetComponentLocation();
박스의 위치를 리턴한다. 여기서 박스의 위치는 박스의 중심값이다.
AActor* Function(TSubclassOf<AActor> ItemClass)
{
}
클래스가 항상 메모리에 로드된 상태에서 바로 접근하는 하드 레퍼런스를 의미한다.
위의 코드에서 TSubclassOf<AActor> ItemClass는 AActor클래스의 하위 클래스들을 모두 포함하게 된다.
TSubclassOf<T>와 다른 소프트 레퍼런스로 포인터로 클래스의 경로만을 저장하여 저장된 클래스에 접근한다.
-> 두 가지 모두 클래스를 참조하기 위한 데이터 구조이다.

언리얼 엔진에선 데이터들을 저장할 수 있는 Data Table를 지원한다.
콘텐츠 브라우저에서 우클릭하여 Miscellaneous에서 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;
데이터 테이블 변수 선언은 이런 식으로 하면 된다.
TArray<FDataTableRow*> AllRows;
static const FString ContextString(TEXT("DataTableContext"));
DataTable->GetAllRows(ContextString, AllRows);
데이터 테이블에서 모든 행을 가져오려면 GetAllRows함수를 사용하여 데이터 테이블의 모든 행들을 가져올 수 있다.
여기서 GetAllRows함수를 사용할 땐 두 개의 매개변수가 필요하다.
FString과 모든 행들을 저장할 TArray<T>가 필요한데, 여기서 FString은 데이터 테이블에서 행을 가져올 때 디버깅 정보를 제공하는데에 사용된다. 데이터 테이블에서 오류가 발생했을 때 이 FString이 오류 메시지에 포함되어서 문제를 추적할 때 도움이 된다.
액터가 데미지를 입고 입히게 하는 로직이다.
UGameplayStatics::ApplyDamage함수로 특정 액터에 데미지 받았다는 신호를 보내면 해당 액터의 TakeDamage함수가 작동하여 해당 액터가 어떤 액터에게 얼마만큼의 데미지를 받았는지를 받아서 함수를 작동시킨다.
static float ApplyDamage(
AActor* DamagedActor,
float BaseDamage,
AController* EventInstigator,
AActor* DamageCauser,
TSubclassOf<class UDamageType> DamageTypeClass
);
DamagedActor : 데미지를 받을 액터입니다. 이 액터는 TakeDamage를 호출하여 데미지를 처리합니다.
BaseDamage : 가하는 기본 데미지 양입니다. TakeDamage에서 이 값을 기반으로 최종 데미지를 계산할 수 있습니다.
EventInstigator : 데미지를 가한 캐릭터의 컨트롤러입니다. (예: 플레이어 캐릭터 또는 AI 컨트롤러)
DamageCauser : 데미지를 유발한 오브젝트입니다. 예를 들어, 발사체, 폭발 또는 근접 무기가 될 수 있습니다.
DamageTypeClass : 데미지 유형을 지정합니다. 기본 데미지 유형은 UDamageType이며, 사용자 정의 데미지 유형을 상속하여 확장할 수 있습니다.
virtual float AActor::TakeDamage(
float DamageAmount,
FDamageEvent const& DamageEvent,
AController* EventInstigator,
AActor* DamageCauser) override;
DamageAmount : 가한 데미지의 양
DamageEvent : 데미지 유형 및 추가 정보를 담고 있는 구조체
EventInstigator : 데미지를 유발한 캐릭터를 제어하는 컨트롤러
DamageCauser : 데미지를 가한 원본 액터 (예: 폭발을 유발한 무기 등).
캐릭터의 체력 및 점수와 같은 캐릭터의 고유 정보들은 보통 PlayerState에 저장한다. PlayerState는 동기화와 관련된 기능들을 제공하기 때문에 멀티 플레이 게임에선 반드시 캐릭터의 정보를 저장할 땐 PlayerState에 저장하지만 싱글 플레이 게임에선 굳이 PlayerState에 정보들을 저장하지 않아도 된다.
GameState : 전역 정보를 저장하는 곳(맵에 스폰된 아이템의 갯수, 진행도, 게임 시작 후 몇 초가 지났는지 등등)
PlayerState : 플레이어 마다의 고유한 정보를 저장
GameState와 Gamemode는 긴밀하게 연동될 수 있도록 설계가 되어 있는데, GameState Base는 간소하게 설계되어 있어서 Gamemode와 GameState Base를 연결지어 사용하면 Gamemode의 기능들을 사용하지 못 하는 순간들이 올 수도 있다.