https://awesometuts.com/blog/unreal-engine-side-scroller-cpp-1/
이 튜토리얼에서는 Unreal Engine과 C++를 사용하여 2.5D 무한 러너 게임을 만들 것입니다.
이 자습서를 위해 자산을 다운로드하고 프로젝트를 완료하십시오.
자산 다운로드
이 튜토리얼을 따라하려면 위의 녹색 자산 다운로드 버튼을 클릭하여 자산을 다운로드하십시오.
다운로드한 폴더에서 코드를 검사하기 위한 참조로 사용할 수 있는 자습서 및 전체 프로젝트의 자산을 찾을 수 있습니다.
시작하기 전에 중요한 정보
다음 창에서 3인칭 프로젝트를 선택하고 블루프린트대신 C++를 선택합니다. 프로젝트를 저장할 위치를 설정하고 이름을 지정합니다. 저는 SideRunner라는 이름을 설정한 다음 프로젝트 생성 버튼을 클릭합니다.
엔진 콘텐츠 활성화
가장 먼저 할 일은 프로젝트와 함께 제공되는 엔진 콘텐츠를 활성화하는 것입니다.
콘텐츠 브라우저에서 오른쪽 하단에 있는 보기 옵션을 클릭합니다:
프로젝트 생성
컨텐츠브라우저의 오른쪽위 Settings를 클릭해서 드롭다운 목록에서 Show Engine Content 확인란을 선택합니다.
이것은 우리가 선택한 삼인칭과 같은 미리 정의된 Unreal Engine 프로젝트와 함께 제공되는 기본적으로 숨겨진 추가 폴더를 표시합니다:
게임플레이 레벨 생성 및 입력 설정
Content 폴더에서 오른쪽 클릭 -> 폴더를 클릭하여 새 폴더를 만들고 이름을 Maps로 지정합니다.
그런 다음 파일 -> 새 수준을 클릭합니다.
새 수준 창에서 기본 수준을 선택합니다.
Ctrl-S로 레벨을 저장합니다. 이름은 Gameplay로 합니다.
다음으로 편집 -> 프로젝트 설정으로 이동합니다.
Project Settings 탭에서 왼쪽의 Input을 클릭하고 Action Mappings 및 Axis Mappings에 대해 다음을 설정합니다.
횡스크롤 게임이기 때문에 A와 D 키를 이용하여 플레이어 캐릭터를 앞뒤로 움직이고, 원한다면 왼쪽 화살표와 오른쪽 화살표 키도 추가할 수 있으며, Space를 사용하여 점프하게 하게 입력 설정을 합니다.
러너 캐릭터 C++ 클래스
이제 Content -> C++ Classes -> SideRunner, Right Click -> New C++ Class에서 필요한 모든 것을 설정했습니다.
새 C++ 클래스는 Character 클래스에서 상속되므로 새 창에서 Character 클래스를 선택하고 다음을 누릅니다.
새 클래스의 이름을 RunnerCharacter로 지정하고 Create Class를 누릅니다.
클래스가 생성되면 Visual Studio에서 자동으로 열립니다. RunnerCharacter.h 및 RunnerCharacter.cpp 클래스에 대해 두 개의 파일이 있음을 알 수 있습니다.
우리는 클래스와 객체에 대한 강의에서 이미 이것에 대해 이야기했고, .h와 .cpp 파일이 하나의 클래스를 나타낸다고 설명했습니다.
.h 파일에서 우리는 클래스의 동작을 모델링합니다. 우리는 클래스가 가질 변수와 함수를 선언합니다.
그리고 .cpp 파일에서 우리는 이러한 기능을 구현합니다. 특정 작업을 수행하도록 함수를 코딩하고 목적에 맞게 선언된 변수를 사용하는 등의 작업을 수행합니다.
전방 선언 및 #include 방지
RunnerCharacter.h 파일을 열고 클래스 선언 맨 아래에서 다음 변수를 선언합니다.
UPROPERTY(VisibleAnywhere)
class UCameraComponent* SideViewcamera;
우리가 쓴 줄을 하나씩 분해해 봅시다.
UPROPERTY는 기본적으로 청사진에 정의한 변수를 노출하는 것과 같은 작업을 도와주는 C++ 매크로이며, 그런 다음 세부 정보 탭에서 해당 변수에 액세스할 수 있습니다.
UPROPERTY에 전달한 VisibleAnywhere 매개변수는 이 속성(변수)이 모든 속성 창에서 표시되지만 편집할 수 없음을 나타냅니다.
UCameraComponent는 레벨에 배치할 수 있는 카메라 개체를 나타내는 클래스이며, UCameraComponent 뒤의 *는 이 변수가 포인터임을 나타내고 해당 변수의 이름은 SideViewCamera입니다.
UCameraComponent 앞의 class 키워드는 UCameraComponent 변수를 전달 선언하는 데 사용됩니다. 그 이유는 RunnerCharacter 클래스에서 UCameraComponent 유형의 변수를 선언하기 때문입니다.
RunnerCharacter 클래스는 UCameraComponent 클래스의 존재를 모릅니다. UCameraComponent 클래스의 존재를 RunnerCharacter 클래스에 알리는 방법은 두 가지입니다.
첫 번째 방법은 #include 키워드를 사용하고 클래스 파일의 맨 위에 UCameraComponent를 포함하는 것입니다. 다른 포함 항목은 다음과 같습니다.
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "RunnerCharacter.generated.h"
// INCLUDING THE CAMERA COMPONENT SO THAT
// THE RunnerCharacter CLASS IS AWARE
// OF ITS EXISTANCE
#include "Camera/CameraComponent.h"
두 번째 방법은 파일에 포함하려는 클래스 앞에 class 키워드를 추가하는 것입니다.
UPROPERTY(VisibleAnywhere)
class UCameraComponent* SideViewCamera;
둘의 차이점은 무엇입니까?
우선 #include를 사용할 때 원하는 클래스의 .h 파일을 포함합니다. 이는 해당 .h 파일의 모든 선언(변수 및 함수)을 포함한다는 의미입니다.
이것은 .h 파일에서 피하고 싶은 것입니다. .cpp 파일에서 사용할 수 있도록 변수를 선언하기만 하면 해당 변수의 모든 선언을 가져올 필요가 없기 때문입니다.
우리의 경우 .h 파일에서 UCameraComponent를 선언하기만 하면 .cpp 파일에서 사용할 수 있으므로 RunnerCharacter.h의 UCameraComponent에 정의된 모든 변수와 함수를 가져올 필요가 없습니다. 파일.
또한 다른 클래스에서 RunnerCharacter 클래스를 사용하려면 RunnerCharacter.h 파일을 가져와야 합니다. 이렇게 하면 RunnerCharacter.h 파일에서 만든 모든 선언과 RunnerCharacter 파일에 있는 모든 h 가져오기를 가져옵니다. 프로젝트가 커지면 보기 흉해질 수 있습니다. 이렇게 하면 컴파일 시간이 길어지고 궁극적으로 프로젝트 속도가 느려집니다.
이 모든 것을 피하기 위해 #include를 사용하는 대신 변수 앞에 클래스를 사용하고 이렇게 하면 선언하는 변수 유형의 존재를 변수를 선언하는 클래스에 알립니다. t 클래스에 있는 모든 선언을 가져옵니다.
그래서 우리가 사용할 때:
UPROPERTY(VisibleAnywhere)
class UCameraComponent* SideViewCamera;
RunnerCharacter 클래스에 UCameraComponent의 존재를 알리고 선언할 수 있지만 모든 선언을 가져오지는 않습니다. 이것은 나중에 수정하기 지루한 실수를 하지 않도록 처음부터 아는 것이 정말 중요합니다.
함수 선언 및 구현 및 코드 컴파일
앞으로 RunnerCharacter 클래스에서 사용할 나머지 변수를 선언할 수 있습니다. SideViewCamera 변수 선언 아래에 다음 코드 줄을 추가합니다.
protected:
void MoveRight(float Value);
public:
void RestartLevel();
UFUNCTION()
void OnOverlapBegin(UPrimitiveComponent* OverlappedComp,
AActor* OtherActor, UPrimitiveComponent* OtherComp,
int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
private:
float zPosition;
FVector TempPos = FVector();
bool CanMove;
MoveRight 기능은 사이드 스크롤러 게임이므로 플레이어 액터를 좌우 또는 앞뒤로 이동하는 데 사용됩니다.
RestartLevel 함수는 자명합니다.
OnOverlapBegin은 다른 액터와 충돌할 때 알려주는 기능입니다. 이것은 플레이어 액터가 게임을 끝내기 위해 그를 쫓는 스파이크나 벽과 충돌하는지 테스트하는 방법입니다.
zPosition 변수는 카메라와 플레이어 액터 사이의 오프셋을 결정하는 데 사용됩니다.
TempPos 변수는 플레이어 액터의 위치에 대한 임시 참조를 저장하는 데 사용됩니다.
그리고 CanMove 변수는 게임에서 플레이어 액터를 움직일 수 있는지 여부를 제어할 것입니다.
RunnerCharacter.h 파일에서 선언한 함수에 대해 RunnerCharacter.cpp 파일 내에 정의를 만드는 것을 잊지 마십시오.
void ARunnerCharacter::MoveRight(float Value)
{
}
void ARunnerCharacter::RestartLevel()
{
}
void ARunnerCharacter::OnOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor,
UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
}
위의 코드를 복사하여 RunnerCharacter.cpp 파일에 붙여넣거나 여기를 클릭하여 .cpp 파일에서 함수 정의를 생성하기 위한 바로 가기를 표시하는 이 가이드를 따를 수 있습니다.
이제 코드를 컴파일할 수 있습니다. 그렇게 하려면 CTRL + SHIFT + B를 누르거나 빌드 -> 솔루션 빌드로 이동할 수 있습니다.
새 코드를 작성하거나 기존 코드를 변경할 때마다 위의 프리뷰에서 본 것과 같은 방식으로 컴파일해야 해당 변경 사항이 언리얼 엔진 에디터에 반영됩니다.
코드를 컴파일하지 않으면 언리얼 엔진 에디터에서 사용할 수 없기 때문에 이것은 정말 중요합니다.
예를 들어 플레이어 액터의 점프 기능을 생성했지만 Visual Studio에서 코드를 컴파일하지 않으면 에디터에서 게임을 테스트할 때 플레이어 액터가 점프할 수 없습니다.
툴바에 있는 컴파일 버튼을 눌러 언리얼 엔진 에디터에서 코드를 컴파일할 수도 있습니다:
이 튜토리얼의 다음 섹션으로 이동하기 전에 RunnerCharacter 클래스의 .h 및 .cpp 파일에 대해 지금까지 작성한 전체 코드를 그대로 둡니다.
모든 것이 정상이고 실수하지 않았는지 확인하기 위해 이 코드를 내 코드와 비교하기 위한 참조로 사용할 수 있습니다.
RunnerCharacter.h:
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "RunnerCharacter.generated.h"
UCLASS()
class SIDERUNNER_API ARunnerCharacter : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
ARunnerCharacter();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
UPROPERTY(VisibleAnywhere)
class UCameraComponent* SideViewCamera;
protected:
void MoveRight(float Value);
public:
void RestartLevel();
UFUNCTION()
void OnOverlapBegin(UPrimitiveComponent* OverlappedComp,
AActor* OtherActor, UPrimitiveComponent* OtherComp,
int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
private:
float zPosition;
FVector TempPos = FVector();
bool CanMove;
};
RunnerCharacter.cpp
#include "RunnerCharacter.h"
// Sets default values
ARunnerCharacter::ARunnerCharacter()
{
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void ARunnerCharacter::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void ARunnerCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
void ARunnerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
}
void ARunnerCharacter::MoveRight(float Value)
{
}
void ARunnerCharacter::RestartLevel()
{
}
void ARunnerCharacter::OnOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor,
UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
}
클래스의 .CPP 파일에 #include 추가
이제 필요한 모든 변수와 함수를 선언하고 함수의 정의를 만들었으므로 기능 코드를 스크립트에 추가할 수 있습니다.
RunnerCharacter.cpp 파일로 이동하고 가장 먼저 할 일은 사용하려는 클래스에 대한 포함을 추가하는 것입니다. 클래스 선언 위에 다음 코드 줄을 추가합니다.
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
“그럼 이 선생님은? 처음에 #include를 사용하지 말라고 했는데 지금 사용하고 있습니다. 미쳤습니까?”
이 튜토리얼의 전방 선언 및 #include 피하기 섹션에서 우리는 항상 전방 선언을 사용하고 #include 사용을 피하고 싶다고 언급했지만 .h 파일에 대한 것입니다. 나는 그 변수와 함수를 사용한다는 것을 의미합니다. 우리는 .h 파일을 사용하여 해당 클래스를 가져옵니다.
그러나 .cpp 파일에서는 .h 파일에서 선언한 모든 기능을 구현하므로 .cpp 파일에서 #include를 사용해도 문제가 없습니다.
게다가 사용하려는 클래스의 .h 파일을 포함하지 않으면 사용할 수 없습니다.
무엇을 포함해야 하는지 어떻게 알 수 있습니까?
클래스를 포함하는 코드 행을 보면 CameraComponent 클래스 또는 다른 클래스를 포함하기 위해 무엇을 입력해야 하는지 어떻게 알 수 있는지 궁금할 것입니다.
알아 내기가 매우 쉽습니다. 여기를 클릭하여 언리얼 엔진의 API 레퍼런스 웹페이지로 이동하세요. "unreal engine api"를 검색하고 첫 번째 링크를 클릭하여 Google에서 검색할 수도 있습니다.
API 웹 페이지에서 오른쪽 상단의 검색 표시줄을 사용하여 검색하려는 클래스의 이름을 입력합니다. 예를 들어 "UCameraComponent"를 입력할 수 있습니다.
When you do that, on the next page scroll down until you find the #include of the specific class that you are looking for:
빨간색 사각형에 표시되는 코드는 특정 클래스를 포함하기 위해 복사하여 .cpp 파일에 붙여넣어야 하는 코드입니다.
이렇게 하면 프로젝트에서 사용할 모든 클래스에 대한 포함을 쉽게 찾을 수 있습니다.
RunnerCharacter.cpp 클래스 코딩하기
RunnerCharacter.cpp 클래스로 돌아갑니다. 우리가 작성한 포함에 대해 설명하겠습니다.
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
우리는 이미 CameraComponent.h가 무엇인지 알고 있으므로 건너뛸 것입니다. CapsuleComponent.h를 사용하면 Capsule Component 클래스의 기능을 사용할 수 있습니다.
우리가 물려받은 Character 클래스와 함께 제공되는 Capsule Component를 조작하고 싶기 때문에 이것이 필요합니다.
CharacterMovementComponent.h는 액터의 움직임을 제어하는 컴포넌트입니다. 이것은 우리가 물려받은 Character 클래스와 함께 제공되며 속도, 점프력 및 기타 걷기 및 달리기 관련 속성에 영향을 미치는 옵션이 있습니다.
이제 문제를 해결했으므로 필요한 모든 변수를 초기화하겠습니다. ARunnerCharacter() 생성자 내부에 다음 코드 줄을 추가합니다.
ARunnerCharacter::ARunnerCharacter()
{
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
GetCapsuleComponent()->InitCapsuleSize(42.f, 96.f);
SideViewCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("Side View Camera"));
SideViewCamera->bUsePawnControlRotation = false;
GetCharacterMovement()->bOrientRotationToMovement = true;
GetCharacterMovement()->RotationRate = FRotator(0.0f, 720.0f, 0.0f);
GetCharacterMovement()->GravityScale = 2.0f;
GetCharacterMovement()->AirControl = 0.8f;
GetCharacterMovement()->JumpZVelocity = 1000.0f;
GetCharacterMovement()->GroundFriction = 3.0f;
GetCharacterMovement()->MaxWalkSpeed = 600.0f;
GetCharacterMovement()->MaxFlySpeed = 600.0f;
TempPos = GetActorLocation();
zPosition = TempPos.Z + 300.0f;
}
우리가 작성한 코드를 한 줄씩 분석해 봅시다.
6행: 먼저 Capsule 구성 요소에 대한 참조를 가져오고 너비와 높이에 대한 초기 크기를 설정합니다.
8행: CreateDefaultSubobject 함수를 사용하여 Camera 구성 요소를 만듭니다. <> 내부에 우리가 만들고자 하는 객체의 유형을 전달합니다. 우리의 경우 Camera 구성 요소이고 TEXT를 사용하여 청사진 편집기에 표시될 해당 객체의 이름을 전달합니다.
10행: CharacterMovement 구성 요소에 대한 참조를 가져오고 CharacterMovement 구성 요소를 들고 있는 액터가 움직이는 방향으로 회전하도록 지정합니다.
11행 : CharacterMovement 구성 요소가 회전하는 속도와 같은 회전 속도를 사용합니다. 플레이어 액터는 Y축에서만 회전하므로 X와 Z에 0 값을 사용했습니다.
13행: 중력 스케일을 2로 설정하여 중력이 플레이어 액터에 미치는 영향을 결정합니다. 1은 일반 중력이고 2는 중력이 플레이어 액터에 두 배로 영향을 미친다는 것을 의미합니다.
14행: 공중 제어를 0.8로 설정하여 플레이어 액터가 공중에 있는 동안 움직임을 제어하는 데 영향을 줍니다.
15행: 점프 속도는 기본적으로 액터의 점프력인 1000으로 설정됩니다.
16행: 그라운드 마찰은 3으로 설정되어 그라운드와 액터 사이의 마찰에 영향을 미칩니다.
17행 및 18행: 최대 보행 속도는 최대 비행 속도와 마찬가지로 자명합니다. 하나는 플레이어 액터의 속도에 영향을 미치고 다른 하나는 공중에 있는 플레이어의 속도에 영향을 줍니다.
21행: 플레이어 액터의 현재 위치를 TempPos 변수에 저장합니다.
22행: zPosition의 값을 TempPos.Z + 300의 현재 위치로 설정합니다. 즉, 플레이어 액터에서 카메라의 오프셋이 300이 됩니다.
플레이어 액터의 이동은 MoveRight 함수에서 발생하므로 내부에 다음 코드 줄을 추가합니다.
void ARunnerCharacter::MoveRight(float Value)
{
if (CanMove)
AddMovementInput(FVector(0.0f, 1.0f, 0.0f), Value);
}
플레이어 액터가 움직일 수 있는지 여부를 제어하기 위해 CanMove 부울 변수를 사용합니다. CanMove가 true이면 이동할 수 있고, CanMove가 false이면 플레이어 액터가 장애물과 충돌할 때 발생하므로 이동할 수 없습니다.
게임이 시작되면 플레이어 액터가 움직일 수 있기 때문에 BeginPlay 함수 내에서 CanMove를 true로 설정해야 합니다.
void ARunnerCharacter::BeginPlay()
{
Super::BeginPlay();
CanMove = true;
}
이 작업을 수행하려면 MoveRight 함수를 설정한 입력에 바인딩해야 합니다. SetupLayerInputComponent 함수에서 다음 코드 줄을 추가합니다.
void ARunnerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);
PlayerInputComponent->BindAction("Jump", IE_Released, this, &ACharacter::StopJumping);
PlayerInputComponent->BindAxis("MoveRight", this, &ARunnerCharacter::MoveRight);
}
InputComponent 클래스의 BindAction 함수를 사용하여 클래스의 함수를 프로젝트 설정 -> 입력에서 정의한 작업에 바인딩합니다. 그리고 BindAxis를 사용하여 입력 설정에서 정의한 축에 함수를 바인딩합니다.
우리는 우리가 상속한 Character 클래스에 정의된 내장 점프 함수를 사용하고 입력에서 설정한 점프 동작에 바인딩합니다.
5행에서 IE_Pressed 매개변수를 사용합니다. 즉, 점프 동작을 트리거하는 버튼을 누를 때 함수가 실행된다는 의미이고, 6행에서 IE_Released를 사용합니다. 즉, 점프를 트리거하는 버튼에서 손을 떼면 함수가 호출된다는 의미입니다. 행동.
버튼을 누르면 Character 클래스에 정의된 Jump 함수가 호출되고 버튼을 놓으면 역시 Character 클래스에 정의된 StopJumping 함수가 호출됩니다.
그리고 MoveRight 축 매핑을 트리거하는 버튼을 누르면 RunnerCharacter 클래스에 정의된 MoveRight 함수를 호출합니다.
매핑 이름을 매개 변수로 전달할 때 작업에서 정의한 사례 이름 또는 입력의 축 매핑과 일치해야 합니다. MoveRight와 같은 축 매핑을 정의한 경우 코드에서 MoveRight도 호출해야 합니다.
moveRight를 입력하면 소문자로 m을 입력했지만 대문자 M으로 정의했기 때문에 작동하지 않습니다. 이는 명심해야 할 정말 중요합니다.
마지막 단계는 카메라가 Tick 함수에서 발생할 플레이어 액터를 따르도록 만드는 것입니다.
void ARunnerCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
TempPos = GetActorLocation();
TempPos.X -= 850.0f;
TempPos.Z = zPosition;
SideViewCamera->SetWorldLocation(TempPos);
}
Tick 함수는 매 프레임마다 호출되며 이 경우 플레이어를 따라가는 카메라와 같이 게임이 실행되는 동안 업데이트해야 하는 게임의 모든 부분을 업데이트하는 데 사용할 수 있습니다.
언리얼 레벨에디터에 돌아와 CTRL+ALT+F11을 눌러 컴파일 저장합니다.
이미 언급했듯이 클래스를 변경할 때마다 이 작업을 수행해야 합니다.
러너 캐릭터 블루프린트 만들기
RunnerCharacter 클래스가 준비되는 동안에는 해당 클래스에서 청사진을 생성할 때까지 게임을 테스트할 수 없습니다.
게임에서 클래스를 추가할 수 없기 때문에 청사진은 게임에서 RunnerCharacter 액터를 나타냅니다. 클래스에서 청사진을 생성하고 게임에서 해당 청사진을 사용해야 합니다. 그 청사진에는 클래스에서 만든 모든 기능이 포함됩니다.
이 작업을 수행하기 전에 먼저 Content 최상위 계층에 새 폴더를 만듭니다. 마우스 오른쪽 버튼 -> 새 폴더를 클릭하고 이름을 Blueprints로 지정합니다.
Blueprint 폴더에서 마우스 오른쪽 버튼 -> Blueprint Class를 클릭하고 Pick Parent Class 창에서 모든 클래스의 드롭다운 목록을 클릭하고 RunnerCharacter 클래스를 검색한 다음 생성한 RunnerCharacter 클래스를 선택하고 선택 버튼을 클릭합니다.
청사진이 생성되면 이름을 BP_RunnerCharacter로 지정하고 청사진 편집기에서 엽니다.
Character 클래스를 상속받았기 때문에 이미 Capsule 컴포넌트, Skeletal Mesh 컴포넌트, Character Movement 컴포넌트를 마음대로 사용할 수 있습니다.
Viewport 탭에서 Capsule 컴포넌트를 볼 수도 있습니다.
언리얼 엔진 튜토리얼을 따라오셨다면 아마 이미 보셨겠지만, 코드로 작업하고 코드를 통해 이러한 구성 요소에 액세스할 때 시각적으로 볼 수 없습니다. 이 자습서의 이전 단계에서 코드에서 액세스한 구성 요소를 보여 주는 이유입니다.
눈에 띄는 또 다른 구성 요소는 코드에서 생성한 카메라 구성 요소입니다. 구성 요소의 이름이 코드에서 설정한 것과 동일한 이름인 Side View Camera이고 뷰포트 탭에서도 카메라를 볼 수 있습니다.
앞으로 이동하여 Components 탭에서 Mesh 컴포넌트를 선택하고 디테일 탭의 Mesh 설정에서 Skeletal Mesh에 대해 3인칭 프로젝트 파일에서 사용 가능한 SK_Mannequin 모델을 선택합니다.
메시 구성요소에 대해 Z 위치 및 Z 회전을 -90으로 설정합니다. 카메라와 방향을 맞춰 앞을 보게 됩니다.
Details 탭의 Animation 설정에서 Anim Class 드롭다운 목록을 클릭하고 Mesh 구성 요소의 애니메이터 청사진으로 ThirdPerson_AnimBP를 선택합니다. 전 ABP_Manny_C를 선택했습니다.
우리가 만든 모든 변경 사항을 컴파일하고 저장했는지 확인하십시오. 그러면 뷰포트 창에서 캐릭터가 애니메이션되는 방식을 볼 수 있습니다.
사이드 러너 게임 모드 청사진
지금 게임을 실행하면 레벨에서 3인칭 프로젝트와 함께 제공되는 기본 플레이어 액터를 볼 수 있습니다. 방금 생성한 액터를 배치하기 위해, 예를 들어. BP_RunnerCharacter, 커스텀 게임 모드를 만들어야 합니다.
게임 모드가 무엇이고 게임 모드의 목적이 무엇인지 모르는 경우 튜토리얼을 진행하기 전에 여기를 클릭하여 해당 개념에 대해 알아보십시오.
Content -> Blueprints 폴더 안에서 우클릭 -> Blueprint Class를 클릭합니다. 게임 모드에 대한 검색 표시줄 필터의 팝업 창 내에서 목록에서 GameMode 클래스를 선택합니다.
새 청사진의 이름을 BP_SideRunner_GameMode로 지정합니다. 다음으로 Edit -> Project Settings -> Maps & Modes로 이동하고 Default Modes에서 BP_SideRunner_GameMode를 선택하고 Default Pawn Class로 BP_RunnerCharacter를 선택합니다.
따라서 레벨에 BP_RunnerCharacter 플레이어 액터가 있고, 그는 움직이고 점프할 수 있으며 카메라는 그를 따라갑니다.
카메라는 ZPosition 변수를 사용하여 RunnerCharacter.cpp 클래스에서 정의한 오프셋을 사용합니다. 오프셋 값으로 플레이하고 게임을 테스트하여 얻을 수 있는 다양한 결과를 확인할 수 있습니다.
또한 CanMove 변수의 값을 false로 변경하고 플레이어 액터를 이동하려고 시도하여 그가 이동할 수 없는지 확인할 수 있습니다.
나는 당신이 프로젝트를 실험하고 결과를 보기 위해 주변을 바꾸는 데 익숙해지도록 이러한 작은 변화를 언급하고 있습니다. 이것이 언리얼 엔진과 C++의 작동 방식을 이해하는 가장 좋은 학습 방법이자 가장 빠른 방법입니다.
우리는 플레이어 액터와 관련하여 한 가지 문제가 있습니다. 즉, 그는 가는 방향을 향하지 않고 대신 한 방향을 바라보고 있기 때문에 그의 등은 항상 카메라를 향하고 있습니다.
플레이어 액터를 움직이는 방향으로 회전시키기
회전 문제를 해결하려면 편집기에서 BP_RunnerCharacter를 열어야 합니다.
구성 요소 창에서 BP_RunnerCharacter(self)를 선택합니다.
세부 정보 탭의 Pawn 설정에서 Use Controller Rotation Yaw 체크박스를 선택 취소합니다.
새로운 변경 사항을 적용하고 저장하고 게임을 다시 테스트해 주십시오.
여기에서 갈 곳
이 자습서에서는 RunnerCharacter 클래스를 만들고 플레이어 액터의 동작을 모델링했습니다. 또한 해당 클래스에서 청사진을 만들고 레벨에서 플레이어의 움직임을 테스트했습니다.
다음 파트인 Create Obstacles And Level Parts For Our Game에서 게임의 장애물과 레벨 파트에 대한 C++ 클래스를 만들고 이러한 클래스에서 청사진을 만들 것입니다.