[UE] Component 컴포넌트, Player 이동

목차
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

'⭐ Unreal Engine > UE RPG Weapon System' 카테고리의 다른 글
[UE] AnimNotify, DoAction (0) | 2023.05.08 |
---|---|
[UE] 무기 장착 및 기본 공격하기 (0) | 2023.05.02 |
[UE] 무기 시스템 설계하기 (0) | 2023.05.01 |
[UE] Interface, AnimNotify, Backstep 구현하기 (0) | 2023.04.28 |
[UE] Player 초기 세팅하기 (0) | 2023.04.26 |
댓글
이 글 공유하기
다른 글
-
[UE] 무기 장착 및 기본 공격하기
[UE] 무기 장착 및 기본 공격하기
2023.05.02목차 Source Characters CAnimInstance.h .cppCPlayer.h .cpp (DoAction 입력만 추가)ICharacter.h .cpp Components CMontagesComponent.h .cpp CMovementComponent.h .cpp CStateComponent.h .cpp CWeaponComponent.h .cpp Notifies CAnimNotify_EndState.h .cppCAnimNotifyState_Equip.h .cpp 생성 Utilities CHelper.hCLog.h .cpp Weapons CAttachment.h .cppCDoAction.h .cpp 생성CEquipment.h .cppCWeaponAsset.h .cppC… -
[UE] 무기 시스템 설계하기
[UE] 무기 시스템 설계하기
2023.05.01목차 Source Characters CAnimInstance.h .cppCPlayer.h .cppICharacter.h .cpp Components CMontagesComponent.h .cpp CMovementComponent.h .cpp CStateComponent.h .cpp CWeaponComponent.h .cpp Notifies CAnimNotify_EndState.h .cpp Utilities CHelper.hCLog.h .cpp Weapons CAttachment.h .cppCEquipment.h .cpp 생성CWeaponAsset.h .cppCWeaponStructures.h .cpp 생성 Global.hCGameMode.h .cppU2212_06.Buil… -
[UE] Interface, AnimNotify, Backstep 구현하기
[UE] Interface, AnimNotify, Backstep 구현하기
2023.04.28목차 Source Characters CAnimInstance.h .cppCPlayer.h .cppICharacter.h .cpp 생성 Components CMontagesComponent.h .cpp CMovementComponent.h .cpp CStateComponent.h .cpp CWeaponComponent.h .cpp Notifies CAnimNotify_EndState.h .cpp 생성 Utilities CHelper.hCLog.h .cpp Weapons CAttachment.h .cpp 생성CWeaponAsset.h .cpp 생성 Global.hCGameMode.h .cppU2212_06.Build.cs U2212_06.uproject 인터페이스 인터… -
[UE] Player 초기 세팅하기
[UE] Player 초기 세팅하기
2023.04.26목차 Source Characters CAnimInstance.h .cppCPlayer.h .cpp Utilities CHelper.hCLog.h .cpp Global.hCGameMode.h .cppU2212_06.Build.cs U2212_06.uproject Player 초기 세팅하기 Utilities 폴더 + Global.h 파일 가져오기 Utilities 폴더 + Global.h 파일을 가져와서 재사용한다. Global.h더보기#pragma once#include "DrawDebugHelpers.h"#include "Kismet/KismetSystemLibrary.h"#include "Kismet/KismetMathLibrary.h"#include "Kismet/Game…
댓글을 사용할 수 없습니다.