[24.08.06]Unreal C++ - 액터의 설계 (이득우의 언리얼 C++ 개발의 정석)

손지·2024년 8월 6일
0

Unreal

목록 보기
32/43

2. 액터의 설계

왜 2부터 시작이냐 하면, 1장은 환경설정 및 개발환경 세팅 이기 때문이다.

월드(World)

유니티에서의 Scene 탭 이다.
언리얼 엔진에서는 월드(World)라도 부른다.

공간(Space)

가상 세계를 구성하는 3차원의 영역을 의미한다. 게임 콘텐츠를 구성하는 물체는 월드의 영역 어딘가에 반드시 존재햐아 하는데. 이를 위해 트랜스폼(Transform) 이라는 구조체를 제공한다. 공간의 기본단위는 cm이다.

시간(Time)

가상 공간에서 흐르는 시간이다. 가상 세계에선의 시간은 초 단위로 현실 세계와 동일하게 흘러가지만, 시간을 멈추거나 느리게 혹은 빠르게 흘러가도록 시간의 스케일을 조정할 수 있다.

물리(Physics)

월드 공간의 배치된 물체에 작용하는 물리적인 환경이다.

렌더링(Rendering)

엔진이 제공하는 시각적인 기능이다. 빛과, 머티리얼로 구성이 된다.
언리얼에서는 물리 기반 렌더링을 제공한다.

액터(Actor)

액터는 언리얼 엔진에서 콘텐츠를 구성하는 최소 단위의 물체 이다.
액터는 다음과 같은 요소로 구성된다.

이름 : 액터의 명칭
유형 : 게임플레이에서의 수행할 역할
트랜스폼 : 반드시 액터에 존재해야 하므로 항상 트랜스폼이 부여된다.
프로퍼티 : 액터에 설정된 속성 값이다.
게임 로직 : 액터의 특정 상황이 발생할대 이에 대응할 구체적인 행동이다.
언리얼 엔진에서는 블루프린트와 C++ 을 지원한다.

레벨(Level)

사전적으로 "수준" 이라는 뜻이지만 게임 개발 관점에서는 '플레이어에게 주어지는 스테이지'를 의미합니다.

컴포넌트(Component)

게임에서 액터의 주요 기능은 크게 3가지이다.

시작적, 물리적 기능, 그리고 움직임 이다.
플레이어에게 어떻게 보여질 것인지, 또 어떠한 상호작용을 할것이며 어떤 움직임을 가질 것인지 이다.

액터를 설계할때 다양한 경우에 유연하게 대처하기위해 언리얼 엔진은 각 기능을 규격화 하고 액터가 이들을 조합할 수 있도록 설계하였다. 이러한 규격화된 기능을 컴포넌트라고 한다.

스태틱메시 (Static Mesh)

애니메이션이 없는 모델링 애셋인 스태틱메시를 사용해 시각적인 기능과 물리적인 기능을 제공하는 모듈이다. 주로 배경 물체에 사용한다.

스켈레탈메시 (SkeletalMesh)

애니메이션 정보가 있는 모델링 애셋인 스켈레탈 메시를 사용해 시각적인 기능과 애니메이션, 그리고 캐릭터의 물리 기능을 제공하는 모듈이다. 주로 캐릭터에 사용한다.

콜리전 (Collision)

구/박스/캡슐로 지정한 영역에 물리적인 긴능을 설정하기 위해 제공하는 모듈이다. 시각적인 기능은없다. 이점은 유니티엔진과 유사한것같다.

카메라 (Camera)

가상 세계에서 보여지는 현재 상황을 플레이어의 모니터 화면에 출력해주는 기능이다.

오디오 (Audio)

가상 세계에서 소리를 발생시키는 데 사용하는 기능이다.

파티클 시스템(Particle System)

파티클 시스템으로 설계된 이펙트를 화면에 보여주기 위한 기능이다.

라이트(Light)

전구, 헤드라이트 등과 같이 물체에 광원 효과를 부여하는 기능이다.

무브먼트(Movement)

물체에 특정한 움직임을 부여하는 기능이다.

액터는 여러 개의 컴포넌트를 가질수 있으며, 그중 대표하는 하나의 컴포넌트를 반드시 지정해야한다. 이를 루트 컴포넌트(Root Component) 라고 한다.

실습

먼저 Fountain 이라는 C++클래스를 새로 만든다음 더블클릭 한다.

Fountain.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "EngineMinimal.h"
#include "GameFramework/Actor.h"
#include "Fountian.generated.h"

UCLASS()
class ARENABATTLE_API AFountian : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	AFountian();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

	UPROPERTY(VisibleAnywhere)
	UStaticMeshComponent* Body;
	UPROPERTY(VisibleAnywhere)
	UStaticMeshComponent* Water;

};

Fountian.cpp

// Fill out your copyright notice in the Description page of Project Settings.


#include "Fountian.h"

// Sets default values
AFountian::AFountian()
{
 	// 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 = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("BODY"));
	Water = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Water"));

	RootComponent = Body;
	Water->SetupAttachment(Body);

}

// Called when the game starts or when spawned
void AFountian::BeginPlay()
{
	Super::BeginPlay();
	
}

// Called every frame
void AFountian::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

까지 넣어주면 일단은

위와같이 디테일 패널에서 보이기 시작한다.

그리고 스태틱메시들을 적용 시켜주면 된다.

그리고

Fountain.h

#include "GameFramework/Actor.h"
#include "Fountian.generated.h"

UCLASS()
class ARENABATTLE_API AFountian : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	AFountian();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

	UPROPERTY(VisibleAnywhere)
	UStaticMeshComponent* Body;
	UPROPERTY(VisibleAnywhere)
	UStaticMeshComponent* Water;
	UPROPERTY(VisibleAnywhere)
	UPointLightComponent* Light;
	UPROPERTY(VisibleAnywhere)
	UParticleSystemComponent* Splash;
	UPROPERTY(EditAnywhere, Category=ID)
	int32 ID;
};

Fountain.cpp

// Fill out your copyright notice in the Description page of Project Settings.


#include "Fountian.h"

// Sets default values
AFountian::AFountian()
{
 	// 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 = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("BODY"));
	Water = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Water"));
	Light = CreateDefaultSubobject<UPointLightComponent>(TEXT("Light"));
	Splash = CreateDefaultSubobject<UParticleSystemComponent>(TEXT("SPLASH"));


	RootComponent = Body;
	Water->SetupAttachment(Body);
	Light->SetupAttachment(Body);
	Splash->SetupAttachment(Body);


	Water->SetRelativeLocation(FVector(0.0f, 0.0f, 135.0f));
	Light->SetRelativeLocation(FVector(0.0f, 0.0f, 195.0f));
	Splash->SetRelativeLocation(FVector(0.0f, 0.0f, 195.0f));

}

// Called when the game starts or when spawned
void AFountian::BeginPlay()
{
	Super::BeginPlay();
	
}

// Called every frame
void AFountian::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

로 바꾸고 적절한 메시를 넣으면

이렇게 파티클과 라이트를 넣은 분수를 만들수 있다.

profile
언리얼 개발자가 될사람

0개의 댓글