[UE] Character, GameMode
언리얼 C++에서 Gamemode(게임 모드)는 게임의 규칙과 플레이어들의 상호작용 방식을 정의하는 클래스다. Gamemode는 게임의 전반적인 진행 방식을 결정하며, 게임의 시작과 종료, 스코어 계산, 게임 오브젝트 생성 등을 담당한다.
목차
Character & Gamemode
Gamemode는 C++ 클래스로 작성되며, 기본적으로 AGameModeBase 클래스를 상속하여 사용한다. Gamemode는 게임 내에서 하나의 인스턴스만 존재하며, 해당 인스턴스를 통해 게임의 전반적인 흐름을 제어한다.
Gamemode 클래스에서는 다음과 같은 기능을 구현할 수 있다.
게임 시작과 종료: Gamemode는 게임이 시작되었을 때와 종료될 때의 로직을 구현한다. 예를 들어, 게임이 시작될 때 플레이어들에게 초기화 작업을 하거나, 게임이 종료될 때 스코어를 계산하는 등의 작업을 수행한다.
게임 규칙: Gamemode는 게임의 규칙을 정의한다. 예를 들어, 게임에서 사용할 무기나 아이템의 종류, 각 플레이어의 생명력과 속도, 게임이 진행되는 지역의 크기와 형태 등을 설정할 수 있다.
플레이어 관리: Gamemode는 플레이어들의 관리를 담당한다. 예를 들어, 플레이어가 게임에 입장할 때의 초기화 작업, 플레이어가 게임에서 나갈 때의 처리, 각 플레이어의 스코어 계산 등을 수행한다.
게임 오브젝트 생성: Gamemode는 게임 오브젝트(게임 내의 모든 객체)의 생성과 소멸을 담당한다. 예를 들어, 적군을 생성하거나, 아이템이나 무기를 배치하는 등의 작업을 수행한다.
Gamemode는 게임의 규칙을 결정하고, 게임 오브젝트를 생성하며, 플레이어 관리를 담당하는 등 매우 중요한 역할을 한다. 게임 개발자는 Gamemode를 통해 게임의 전반적인 진행 방식을 구현할 수 있으며, 플레이어들이 게임을 즐길 수 있도록 만들어낼 수 있다.
01_Spawn | |
C01_Properties.h .cpp C02_Mesh C02_Mesh_Sphere C02_Mesh_Cone C03_Spawner.h .cpp |
|
02_Profiler | |
C01_Log.h .cpp C02_DrawDebug.h .cpp |
|
Utilities | |
CHelpers.h | |
CAnimInstance.h .cpp CGameMode.h .cpp CPlayer |
CHelpers.h
CHelpers.h
#pragma once
#include "CoreMinimal.h"
class U2212_03_API CHelpers
{
public:
template<typename T>
static void CreateComponent(AActor* InActor, T** OutComponent, FName InName, USceneComponent* InParent = nullptr)
{
*OutComponent = InActor->CreateDefaultSubobject<T>(InName);
if (!!InParent)
{
(*OutComponent)->SetupAttachment(InParent);
return;
}
InActor->SetRootComponent(*OutComponent);
}
template<typename T>
static void GetAsset(T** OutObject, FString InPath)
{
ConstructorHelpers::FObjectFinder<T> asset(*InPath);
*OutObject = asset.Object;
}
template<typename T>
static void GetAssetDynamic(T** OutObject, FString InPath)
{
*OutObject = Cast<T>(StaticLoadObject(T::StaticClass(), nullptr, *InPath));
}
template<typename T>
static void GetClass(TSubclassOf<T>* OutClass, FString InPath)
{
ConstructorHelpers::FClassFinder<APawn> asset(*InPath);
*OutClass = asset.Class;
}
};
static void CreateComponent.
- CreateComponent에 USceneComponent를 받아온다.
- USceneComponent* InParent = nullptr 초기값 설정
- if (!!InParent)
- 부모가 있다면(=null이 아니라면)
- (*OutComponent)->SetupAttachment(InParent)
- 부모에 *OutComponent를 붙여준다.
static void GetClass(TSubclassOf<T>* OutClass, FString InPath)
- F12로 들어가서 확인해보면 TSubclassOf도 템플릿으로 정의된 클래스타입이다. TClassType* Class이다. 포인터를 하나 가지고 있다.
- 따라서 TSubclassOf<T>* 는 2차 포인터가 된다.
- CHelper에서 GetClass()를 만든다. 다른곳에서 Class를 생성할 때 CHelper의 GetClass()를 사용하면 좀 더 편하게 생성할 수 있다.
CPlayer 생성
새 C++ 클래스 - Character - CPlayer 생성
캐릭터인 CPlayer를 생성한 후 SpringArm, Camera, Mesh(SK_Mannequin)를 추가한다.
CPlayer.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "CPlayer.generated.h"
UCLASS()
class U2212_03_API ACPlayer : public ACharacter
{
GENERATED_BODY()
private:
UPROPERTY(VisibleAnywhere)
class USpringArmComponent* SpringArm;
UPROPERTY(VisibleAnywhere)
class UCameraComponent* Camera;
public:
// Sets default values for this character's properties
ACPlayer();
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;
private:
void OnMoveForward(float InAxisValue);
void OnMoveRight(float InAxisValue);
void OnHorizontalLook(float InAxisValue);
void OnVerticalLook(float InAxisValue);
};
키 입력
- void OnMoveForward(float InAxisValue);
- void OnMoveRight(float InAxisValue);
- void OnHorizontalLook(float InAxisValue);
- void OnVerticalLook(float InAxisValue);
- ※코딩 컨벤션: 함수 포인터, 이벤트는 앞에 On을 붙여준다.
CPlayer.cpp
#include "CPlayer.h"
#include "Global.h"
#include "GameFramework/SpringArmComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "Components/InputComponent.h"
// Sets default values
ACPlayer::ACPlayer()
{
// 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;
CHelpers::CreateComponent<USpringArmComponent>(this, &SpringArm, "SpringArm", GetCapsuleComponent());
CHelpers::CreateComponent<UCameraComponent>(this, &Camera, "Camera", SpringArm);
USkeletalMesh* mesh;
//SK_Mannequin을 레퍼런스 복사하여 경로를 넣어준다.
CHelpers::GetAsset<USkeletalMesh>(&mesh, "SkeletalMesh'/Game/Character/Mesh/SK_Mannequin.SK_Mannequin'");
GetMesh()->SetSkeletalMesh(mesh);
GetMesh()->SetRelativeLocation(FVector(0, 0, -90));
GetMesh()->SetRelativeRotation(FRotator(0, -90, 0));
bUseControllerRotationYaw = false;
GetCharacterMovement()->bOrientRotationToMovement = true; //이동방향으로 회전
GetCharacterMovement()->MaxWalkSpeed = 400;
SpringArm->SetRelativeLocation(FVector(0, 0, 60));
SpringArm->TargetArmLength = 200;
SpringArm->bUsePawnControlRotation = true;
SpringArm->bEnableCameraLag = true;
}
// Called when the game starts or when spawned
void ACPlayer::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void ACPlayer::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
void ACPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) //입력
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
PlayerInputComponent->BindAxis("MoveForward", this, &ACPlayer::OnMoveForward);
PlayerInputComponent->BindAxis("MoveRight", this, &ACPlayer::OnMoveRight);
PlayerInputComponent->BindAxis("HorizontalLook", this, &ACPlayer::OnHorizontalLook);
PlayerInputComponent->BindAxis("VerticalLook", this, &ACPlayer::OnVerticalLook);
}
void ACPlayer::OnMoveForward(float InAxisValue)
{
FRotator rotator = FRotator(0, GetControlRotation().Yaw, 0);
FVector direction = FQuat(rotator).GetForwardVector();
AddMovementInput(direction, InAxisValue); //이동
}
void ACPlayer::OnMoveRight(float InAxisValue)
{
FRotator rotator = FRotator(0, GetControlRotation().Yaw, 0);
FVector direction = FQuat(rotator).GetRightVector();
AddMovementInput(direction, InAxisValue); //이동
}
void ACPlayer::OnHorizontalLook(float InAxisValue)
{
AddControllerYawInput(InAxisValue);
}
void ACPlayer::OnVerticalLook(float InAxisValue)
{
AddControllerPitchInput(InAxisValue);
}
Component를 사용하기 위해 헤더를 삽입한다.
- #include "GameFramework/SpringArmComponent.h"
- #include "GameFramework/CharacterMovementComponent.h"
- #include "Camera/CameraComponent.h"
- #include "Components/CapsuleComponent.h"
- #include "Components/InputComponent.h"
void ACPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
- PlayerInputComponent는입력을 관장한다.
- PlayerInputComponent의 헤더는 #include "Components/InputComponent.h"
- PlayerInputComponent.h 내부에 있는 BindAxis() 아래 참고.
언리얼 내에서의 회전
- FRotator: 0~360도
- FRotationMatrix: 3x3 행렬
- FQuat: 사원수Quatanium. 회전에 대한 비율을 다루기 때문에 오차가 발생하지 않는다. 짐벌락 현상만 조심하자.
- 언리얼에서는 1:1:1로 매칭되어 서로 바뀔 수 있다.
BindAxis
template<class UserClass>
FInputAxisBinding& BindAxis( const FName AxisName, UserClass* Object, typename FInputAxisHandlerSignature::TUObjectMethodDelegate< UserClass >::FMethodPtr Func )
{
FInputAxisBinding AB( AxisName );
AB.AxisDelegate.BindDelegate(Object, Func);
AxisBindings.Emplace(MoveTemp(AB));
return AxisBindings.Last();
}
BP_Player
CPlayer에서 설정한 값들이 적용되서 들어간다.
헤더명을 모르는 경우 구글에다 검색하여 언리얼 공식문서를 참고하자.
https://docs.unrealengine.com/4.26/en-US/API/Runtime/Engine/GameFramework/USpringArmComponent/
CGameMode
CGameMode.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "CGameMode.generated.h"
UCLASS()
class U2212_03_API ACGameMode : public AGameModeBase
{
GENERATED_BODY()
public:
ACGameMode();
};
CGameMode.cpp
#include "CGameMode.h"
#include "Global.h"
ACGameMode::ACGameMode()
{
//CHelpers를 사용하지 않는 Class 생성 방법
//ConstructorHelpers::FClassFinder<APawn> asset(L"Blueprint'/Game/BP_CPlayer.BP_CPlayer_C'");
//if (asset.Succeeded())
// DefaultPawnClass = asset.Class;
CHelpers::GetClass<APawn>(&DefaultPawnClass, "Blueprint'/Game/BP_CPlayer.BP_CPlayer_C'");
}
ClassType 경로명 작은따옴표(') 앞에 항상 _C를 붙여준다. ex. "Blueprint'/Game/BP_CPlayer.BP_CPlayer_C'"
프로젝트 세팅 - 맵&모드 - 기본 게임모드 CGameMode로 변경.
CAnimInstance
새C++ 클래스 - Anim Instance - CAnimInstance 생성
CAnimInstance.h
#pragma once
#include "CoreMinimal.h"
#include "Animation/AnimInstance.h"
#include "CAnimInstance.generated.h"
UCLASS()
class U2212_03_API UCAnimInstance : public UAnimInstance
{
GENERATED_BODY()
protected:
UPROPERTY(BlueprintReadOnly, Category = "Animation")
float Speed;
public:
//언리얼에서 오버라이딩 했으면 override 붙여준다. 의무사항
void NativeBeginPlay() override;
void NativeUpdateAnimation(float DeltaSeconds) override;
};
CAnimInstance.cpp
#include "CAnimInstance.h"
void UCAnimInstance::NativeBeginPlay()
{
}
void UCAnimInstance::NativeUpdateAnimation(float DeltaSeconds)
{
}
실행화면
'⭐ Unreal Engine > UE FPS TPS' 카테고리의 다른 글
[UE] Collision(Overlap, hit) (0) | 2023.03.09 |
---|---|
[UE] Character Animation, Collsion (0) | 2023.03.08 |
[UE] Log 출력하기, Draw Debug 구현 (0) | 2023.03.03 |
[UE] Mesh, Log (0) | 2023.03.02 |
[UE] Properties (0) | 2023.02.28 |
댓글
이 글 공유하기
다른 글
-
[UE] Collision(Overlap, hit)
[UE] Collision(Overlap, hit)
2023.03.09 -
[UE] Character Animation, Collsion
[UE] Character Animation, Collsion
2023.03.08 -
[UE] Log 출력하기, Draw Debug 구현
[UE] Log 출력하기, Draw Debug 구현
2023.03.03 -
[UE] Mesh, Log
[UE] Mesh, Log
2023.03.02