목차

     

     


     

     

     
    Source
        Characters
        CAnimInstance.h .cpp
    CPlayer.h .cpp
        Components
        CMontagesComponent.h .cpp .생성
    CMovementComponent.h .cpp 생성
    CStateComponent.h .cpp 생성
    CWeaponComponent.h .cpp 생성
        Utilities
        CHelper.h
    CLog.h .cpp
        Global.h
    CGameMode.h .cpp
    U2212_06.Build.cs
        U2212_06.uproject
     

     

     

    Component 만들기 (Movement, State, Montage)

     

     


     

    CMovementComponent 생성

     

    새 C++ 클래스 - ActorComponent - CMovementComponent 생성

     

    CMovementComponent.h

    더보기
    #pragma once
    
    #include "CoreMinimal.h"
    #include "Components/ActorComponent.h"
    #include "CMovementComponent.generated.h"
    
    UENUM()
    enum class ESpeedType : uint8
    {
    	Walk = 0, Run, Sprint, Max,
    };
    
    UCLASS()
    class U2212_06_API UCMovementComponent : public UActorComponent
    {
    	GENERATED_BODY()
    
    private:
    	UPROPERTY(EditAnywhere, Category = "CameraSpeed")
    		float HorizontalLook = 45;
    
    	UPROPERTY(EditAnywhere, Category = "CameraSpeed")
    		float VerticalLook = 45;
    
    private:
    	UPROPERTY(EditAnywhere, Category = "Speed")
    		float Speed[(int32)ESpeedType::Max] = { 200, 400, 600 };
    
    public:
    	FORCEINLINE bool CanMove() { return bCanMove; }
    	FORCEINLINE void Move() { bCanMove = true; }
    	FORCEINLINE void Stop() { bCanMove = false; }
    
    	FORCEINLINE float GetWalkSpeed() { return Speed[(int32)ESpeedType::Walk]; }
    	FORCEINLINE float GetRunSpeed() { return Speed[(int32)ESpeedType::Run]; }
    	FORCEINLINE float GetSprintSpeed() { return Speed[(int32)ESpeedType::Sprint]; }
    
    	FORCEINLINE bool GetFixedCamera() { return bFixedCamera; }
    	FORCEINLINE void EnableFixedCamera() { bFixedCamera = true; }
    	FORCEINLINE void DisableFixedCamera() { bFixedCamera = false; }
    
    public:
    	UCMovementComponent();
    
    protected:
    	virtual void BeginPlay() override;
    
    private:
    	void SetSpeed(ESpeedType InType);
    
    public:
    	void OnSprint();
    	void OnRun();
    	void OnWalk();
    
    	void EnableControlRotation();
    	void DisableControlRotation();
    
    public:
    	void OnMoveForward(float InAxis);
    	void OnMoveRight(float InAxis);
    	void OnHorizontalLook(float InAxis);
    	void OnVerticalLook(float InAxis);
    
    private:
    	class ACharacter* OwnerCharacter;
    
    private:
    	bool bCanMove = true; //이동할 수 있는가
    	bool bFixedCamera; //카메라 고정인가
    };

     

     

     

    CMovementComponent.cpp

    더보기
    #include "Components/CMovementComponent.h"
    #include "Global.h"
    #include "GameFramework/Character.h"
    #include "GameFramework/CharacterMovementComponent.h"
    
    UCMovementComponent::UCMovementComponent()
    {
    
    }
    
    void UCMovementComponent::BeginPlay()
    {
    	Super::BeginPlay();
    
    	OwnerCharacter = Cast<ACharacter>(GetOwner());
    }
    
    void UCMovementComponent::SetSpeed(ESpeedType InType)
    {
    	OwnerCharacter->GetCharacterMovement()->MaxWalkSpeed = Speed[(int32)InType];
    }
    
    void UCMovementComponent::OnSprint()
    {
    	SetSpeed(ESpeedType::Sprint);
    }
    
    void UCMovementComponent::OnRun()
    {
    	SetSpeed(ESpeedType::Run);
    }
    
    void UCMovementComponent::OnWalk()
    {
    	SetSpeed(ESpeedType::Walk);
    }
    
    void UCMovementComponent::EnableControlRotation()
    {
    	OwnerCharacter->bUseControllerRotationYaw = true;
    	OwnerCharacter->GetCharacterMovement()->bOrientRotationToMovement = false;
    }
    
    void UCMovementComponent::DisableControlRotation()
    {
    	OwnerCharacter->bUseControllerRotationYaw = false;
    	OwnerCharacter->GetCharacterMovement()->bOrientRotationToMovement = true;
    }
    
    void UCMovementComponent::OnMoveForward(float InAxis)
    {
    	CheckFalse(bCanMove);
    
    	FRotator rotator = FRotator(0, OwnerCharacter->GetControlRotation().Yaw, 0);
    	FVector direction = FQuat(rotator).GetForwardVector();
    
    	OwnerCharacter->AddMovementInput(direction, InAxis);
    }
    
    void UCMovementComponent::OnMoveRight(float InAxis)
    {
    	CheckFalse(bCanMove);
    
    	FRotator rotator = FRotator(0, OwnerCharacter->GetControlRotation().Yaw, 0);
    	FVector direction = FQuat(rotator).GetRightVector();
    
    	OwnerCharacter->AddMovementInput(direction, InAxis);
    }
    
    void UCMovementComponent::OnHorizontalLook(float InAxis)
    {
    	CheckTrue(bFixedCamera);
    
    	OwnerCharacter->AddControllerYawInput(InAxis * HorizontalLook * GetWorld()->GetDeltaSeconds());
    }
    
    void UCMovementComponent::OnVerticalLook(float InAxis)
    {
    	CheckTrue(bFixedCamera);
    
    	OwnerCharacter->AddControllerPitchInput(InAxis * VerticalLook * GetWorld()->GetDeltaSeconds());
    }

     

     


     

     

    CStateComponent 생성

     

    새 C++ 클래스 - ActorComponent - CStateComponent 생성

     

    CStateComponent.h

    더보기
    #pragma once
    
    #include "CoreMinimal.h"
    #include "Components/ActorComponent.h"
    #include "CStateComponent.generated.h"
    
    UENUM()
    enum class EStateType : uint8
    {
    	Idle = 0, BackStep, Equip, Hitted, Dead, Action, Max,
    };
    DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FStateTypeChanged, EStateType, InPrevType, EStateType, InNewType);
    
    UCLASS()
    class U2212_06_API UCStateComponent : public UActorComponent
    {
    	GENERATED_BODY()
    
    public:
    	FORCEINLINE bool IsIdleMode() { return Type == EStateType::Idle; }
    	FORCEINLINE bool IsBackstepMode() { return Type == EStateType::BackStep; }
    	FORCEINLINE bool IsEquipMode() { return Type == EStateType::Equip; }
    	FORCEINLINE bool IsHittedMode() { return Type == EStateType::Hitted; }
    	FORCEINLINE bool IsDeadMode() { return Type == EStateType::Dead; }
    	FORCEINLINE bool IsActionMode() { return Type == EStateType::Action; }
    
    public:
    	UCStateComponent();
    
    protected:
    	virtual void BeginPlay() override;
    
    public:
    	void SetIdleMode();
    	void SetBackStepMode();
    	void SetEquipMode();
    	void SetHittedMode();
    	void SetDeadMode();
    	void SetActionMode();
    
    private:
    	void ChangeType(EStateType InType);
    
    public:
    	FStateTypeChanged OnStateTypeChanged;
    
    private:
    	EStateType Type;
    };

     

     

     

    CStateComponent.cpp

    더보기
    #include "Components/CStateComponent.h"
    #include "Global.h"
    
    UCStateComponent::UCStateComponent()
    {
    
    }
    
    void UCStateComponent::BeginPlay()
    {
    	Super::BeginPlay();
    
    }
    
    void UCStateComponent::SetIdleMode()
    {
    	ChangeType(EStateType::Idle);
    }
    
    void UCStateComponent::SetBackStepMode()
    {
    	ChangeType(EStateType::BackStep);
    }
    
    void UCStateComponent::SetEquipMode()
    {
    	ChangeType(EStateType::Equip);
    }
    
    void UCStateComponent::SetHittedMode()
    {
    	ChangeType(EStateType::Hitted);
    }
    
    void UCStateComponent::SetDeadMode()
    {
    	ChangeType(EStateType::Dead);
    }
    
    void UCStateComponent::SetActionMode()
    {
    	ChangeType(EStateType::Action);
    }
    
    void UCStateComponent::ChangeType(EStateType InType)
    {
    	EStateType prevType = Type;
    	Type = InType;
    
    	if (OnStateTypeChanged.IsBound())
    		OnStateTypeChanged.Broadcast(prevType, Type);
    }

     

     

     


     

     

     

    CMontageComponent 생성

     

    새 C++ 클래스 - ActorComponent - CMontageComponent 생성

     

     CMontageComponent .h

    더보기
    #pragma once
    
    #include "CoreMinimal.h"
    #include "Components/ActorComponent.h"
    #include "Components/CStateComponent.h"
    #include "Engine/DataTable.h"
    #include "CMontagesComponent.generated.h"
    
    USTRUCT()
    struct FMontageData
    	: public FTableRowBase
    {
    	GENERATED_BODY()
    
    public:
    	UPROPERTY(EditAnywhere)
    		EStateType Type; //상태 Type
    
    	UPROPERTY(EditAnywhere)
    		class UAnimMontage* Montage;
    
    	UPROPERTY(EditAnywhere)
    		float PlayRate = 1; //Player 속도
    };
    
    UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
    class U2212_06_API UCMontagesComponent : public UActorComponent
    {
    	GENERATED_BODY()
    
    private:
    	UPROPERTY(EditAnywhere, Category = "DataTable")
    		UDataTable* DataTable;
    
    public:
    	UCMontagesComponent();
    
    protected:
    	virtual void BeginPlay() override;
    
    public:
    	void PlayBackStepMode();
    
    private:
    	void PlayAnimMontage(EStateType InType);
    
    private:
    	class ACharacter* OwnerCharacter;
    	FMontageData* Datas[(int32)EStateType::Max];
    };

     

     

     

     CMontageComponent .cpp

    더보기
    #include "Components/CMontagesComponent.h"
    #include "Global.h"
    #include "GameFramework/Character.h"
    
    UCMontagesComponent::UCMontagesComponent()
    {
    }
    
    void UCMontagesComponent::BeginPlay()
    {
    	Super::BeginPlay();
    
    	if(DataTable == nullptr)//DataTable이 없다면
    	{   //DataTable이 없다고 메시지를 띄워준다.
    		GLog->Log(ELogVerbosity::Error, "DataTable is not selected");
    
    		return;
    	}
    
    	OwnerCharacter = Cast<ACharacter>(GetOwner());
    
    	TArray<FMontageData*> datas;
    	DataTable->GetAllRows<FMontageData>("", datas);//전체 데이터를 가져온다.
    
    	//가져온 데이터를 배열에 넣어준다.
    	for (int32 i = 0; i< (int32)EStateType::Max; i++)
    	{
    		for(FMontageData* data : datas)
    		{
    			if((EStateType)i == data->Type)
    			{
    				Datas[i] = data;
    
    				continue;
    			}
    		}//for(data)
    	}//for(i)
    }
    
    //#define LOG_UCMontagesComponent 1
    #if LOG_UCMontagesComponent
    for (FMontagesData* data : datas)
    {
    	if (data == nullptr)
    		continue;
    
    	FString str;
    	//Static이 붙는 애들은 Reflection(자료형의 타입을 변수로 다룰 수 있게 해준다).
    	str.Append(StaticEnum<EStateType>()->GetValueAsString(data->Type));//Enum을 문자열로 바꾸어서 자료형의 이름을 가져온다.
    	str.Append(" / ");
    	str.Append(data->Montage->GetPathName());
    
    	CLog::Log(str);
    }
    #endif
    
    
    void UCMontagesComponent::PlayBackStepMode()
    {
    	PlayAnimMontage(EStateType::BackStep);
    }
    
    void UCMontagesComponent::PlayAnimMontage(EStateType InType)
    {
    	CheckNull(OwnerCharacter);
    
    	FMontageData* data = Datas[(int32)InType];
    
    	if(data == nullptr || data->Montage == nullptr)
    	{
    		GLog->Log(ELogVerbosity::Error, "None montages data");
    
    		return;
    	}
    
    	OwnerCharacter->PlayAnimMontage(data->Montage, data->PlayRate);//data의 몽타주를 PlayRate속도로 OwnerCharacter에 적용하여 재생.
    }

     

     


     

     

    CPlayer 생성

     

    CPlayer.h

    더보기
    #pragma once
    
    #include "CoreMinimal.h"
    #include "GameFramework/Character.h"
    #include "Components/CStateComponent.h"
    #include "CPlayer.generated.h"
    
    UCLASS()
    class U2212_06_API ACPlayer : public ACharacter
    {
    	GENERATED_BODY()
    
    private:
    	UPROPERTY(VisibleAnywhere)
    		class USpringArmComponent* SpringArm;
    
    	UPROPERTY(VisibleAnywhere)
    		class UCameraComponent* Camera;
    
    private:
    	UPROPERTY(VisibleAnywhere)
    		class UCMontagesComponent* Montages;
    
    	UPROPERTY(VisibleAnywhere)
    		class UCMovementComponent* Movement;
    
    	UPROPERTY(VisibleAnywhere)
    		class UCStateComponent* State;
    
    public:
    	ACPlayer();
    
    protected:
    	virtual void BeginPlay() override;
    
    public:	
    	virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
    
    private:
    	UFUNCTION()
    		void OnStateTypeChanged(EStateType InPrevType, EStateType InNewType);
    
    private:
    	void OnAvoid();
    
    private:
    	void BackStep();
    };

     

     

    CPlayer.cpp

    더보기
    #include "Characters/CPlayer.h"
    #include "Global.h"
    #include "CAnimInstance.h"
    #include "GameFramework/SpringArmComponent.h"
    #include "GameFramework/CharacterMovementComponent.h"
    #include "Camera/CameraComponent.h"
    #include "Components/SkeletalMeshComponent.h"
    #include "Components/InputComponent.h"
    #include "Components/CMontagesComponent.h"
    #include "Components/CMovementComponent.h"
    
    ACPlayer::ACPlayer()
    {
    	CHelpers::CreateComponent<USpringArmComponent>(this, &SpringArm, "SpringArm", GetMesh());
    	CHelpers::CreateComponent<UCameraComponent>(this, &Camera, "Camera", SpringArm);
    
    	CHelpers::CreateActorComponent<UCMontagesComponent>(this, &Montages, "Montage");
    	CHelpers::CreateActorComponent<UCMovementComponent>(this, &Movement, "Movement");
    	CHelpers::CreateActorComponent<UCStateComponent>(this, &State, "State");
    
    	GetMesh()->SetRelativeLocation(FVector(0, 0, -90));
    	GetMesh()->SetRelativeRotation(FRotator(0, -90, 0));
    
    	USkeletalMesh* mesh;
    	CHelpers::GetAsset<USkeletalMesh>(&mesh, "SkeletalMesh'/Game/Character/Mesh/SK_Mannequin.SK_Mannequin'");
    	GetMesh()->SetSkeletalMesh(mesh);
    
    	TSubclassOf<UCAnimInstance> animInstance;
    	CHelpers::GetClass<UCAnimInstance>(&animInstance, "AnimBlueprint'/Game/ABP_Character.ABP_Character_C'");
    	GetMesh()->SetAnimClass(animInstance);
    
    	SpringArm->SetRelativeLocation(FVector(0, 0, 140));
    	SpringArm->SetRelativeRotation(FRotator(0, 90, 0));
    	SpringArm->TargetArmLength = 200;
    	SpringArm->bDoCollisionTest = false;
    	SpringArm->bUsePawnControlRotation = true;
    	SpringArm->bEnableCameraLag = true;
    
    	GetCharacterMovement()->RotationRate = FRotator(0, 720, 0);
    
    }
    
    void ACPlayer::BeginPlay()
    {
    	Super::BeginPlay();
    
    	Movement->OnRun(); //Movement의 기본을 Run으로 설정
    	Movement->DisableControlRotation();//Movement의 기본을 DisableControlRotation으로 설정
    
    	State->OnStateTypeChanged.AddDynamic(this, &ACPlayer::OnStateTypeChanged);
    }
    
    void ACPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
    {
    	Super::SetupPlayerInputComponent(PlayerInputComponent);
    
    	PlayerInputComponent->BindAxis("MoveForward", Movement, &UCMovementComponent::OnMoveForward);
    	PlayerInputComponent->BindAxis("MoveRight", Movement, &UCMovementComponent::OnMoveRight);
    	PlayerInputComponent->BindAxis("VerticalLook", Movement, &UCMovementComponent::OnVerticalLook);
    	PlayerInputComponent->BindAxis("HorizontalLook", Movement, &UCMovementComponent::OnHorizontalLook);
    
    	PlayerInputComponent->BindAction("Sprint", EInputEvent::IE_Pressed, Movement, &UCMovementComponent::OnSprint);
    	PlayerInputComponent->BindAction("Sprint", EInputEvent::IE_Released, Movement, &UCMovementComponent::OnRun);
    
    	PlayerInputComponent->BindAction("Avoid", EInputEvent::IE_Pressed, this, &ACPlayer::OnAvoid);
    }
    
    void ACPlayer::OnStateTypeChanged(EStateType InPrevType, EStateType InNewType)
    {
    	switch (InNewType)
    	{
    		case EStateType::BackStep: BackStep(); break;
    	}
    }
    
    void ACPlayer::OnAvoid()
    {
    	CheckFalse(State->IsIdleMode());
    	CheckFalse(Movement->CanMove());
    
    	CheckTrue(InputComponent->GetAxisValue("MoveForward") >= 0.0f);//뒷방향을 입력했다면
    
    	State->SetBackStepMode();//State을 BackStepMode로 변경한다.
    }
    
    void ACPlayer::BackStep()
    {
    	Movement->EnableControlRotation();//정면을 바라본 상태로 뒤로 뛰어야하기 때문에 EnableControlRotation으로 만들어준다.
    
    	Montages->PlayBackStepMode();//PlayBackStepMode()를 통해 몽타주 재생.
    }

     

     


     

     

    이론 설명

     


     

    UCLASS 접근을 제한하는 방법

     

    • 열어두면 기획이나 디자이너가 접근하여 수정할 수 있다.  

    • 프로그래머만 접근할 수 있다.

     

     

    원격 빌드 원리

     

    CI, CD, CD 

    DevOps

     

     

    Jenkins    ←    Repo

                              ↑ push

                           소스(clinet)   원격빌드

     

     


     

     

     

     

    언리얼 에디터 상에서의 작업

     


     

     

     

    StepBack 몽타주 생성

     


     

     

     

     

    DT_Player (csv. 파일 + DataTable 만들기)

     

    액셀로 csv 파일을 만들어 DT_Player라고 이름 짓고 저장한다.

    • 첫번째 열에 인덱스 숫자 기입
    • 두번재 열에 Type 이름 넣기 (여기서는 BackStep)
    • 세번째 열에 언리얼 내에 저장된 Montage를 레퍼런스 복사하여 넣는다.
    • 네번째 열에 PlayRate(재생속도)를 기입한다.

     

     

     

    DT_Player 

     


     

     

    ABP_Player

     

    AnimGraph

     

     


     

     

     

    실행화면 - Stepback