일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- pdlc
- 게임개발
- 유스케이스
- 유니티
- MAC
- AINCAA
- dtft
- stride
- Race condition
- linear difference equation
- frequency-domain spectrum analysis
- 배경 그림
- Rr
- CTF
- DP
- TSet
- RBAC
- dirty cow
- 언리얼엔진
- sampling theory
- DSP
- ret2libc
- STCF
- Security
- 메카님
- MLFQ
- Double free
- 운영체제
- Unity #Indie Game
- 게임 개발
- Today
- Total
다양한 기록
[UE Game Framework] #3 Character Control Setting 본문
캐릭터 컨트롤 요소
- 일반적으로 컨트롤러와 폰, 카메라, 스프링암, 캐릭터 무브먼트 다섯가지 요소
- 컨트롤러: 입력자의 의지(목표 지점)을 지정시 사용, ControlRotation 속성
- 폰: 폰의 트랜스폼을 지정
- 카메라: 화면 구도를 설정하기 위해 사용, 주로 1인칭 시점에서 사용
- 스프링암: 화면 구도를 설정하기 위해 사용, 주로 3인칭 시점에서 사용
- 캐릭터 무브먼트: 캐릭터의 이동과 회전을 조정하는 용도로 사용
Desired Rotation : 내가 앞으로 회전해야 할 최종 목표, 의지를 나타내는 회전값
Rotation : 현재 회전된 상태
Desired Rotation으로 값을 덮어씌우고 필요 시 Rotation rate로 지정된 각속도로 회전
폰의 이동 함수
Look 함수 : 마우스 입력으로부터 컨트롤러의 컨트롤 회전을 설정
Move 함수 : 컨트롤러의 컨트롤 회전으로부터 Yaw 값을 참고해 이동 방향을 설정
콘솔 커맨드 창(단축키 ~)으로부터 Control Rotation 값을 확인 가능
Control Rotation으로 이동과 시점을 조절
void AABCharacterPlayer::Look(const FInputActionValue& Value)
{
FVector2D LookAxisVector = Value.Get<FVector2D>();
AddControllerYawInput(LookAxisVector.X);
AddControllerPitchInput(LookAxisVector.Y);
}
인풋값을 받아 AddControllerYawInput랑 AddControllerPitchInput을 실행함
플레이어 컨트롤러의 포인트를 가져와 AddYawInput 실행
로테이션 인풋 속성의 Yaw 회전 값에 집어넣은 입력의 크기를 추가해줌
void APlayerController::UpdateRotation( float DeltaTime )
{
// Calculate Delta to be applied on ViewRotation
FRotator DeltaRot(RotationInput);
FRotator ViewRotation = GetControlRotation();
if (PlayerCameraManager)
{
PlayerCameraManager->ProcessViewRotation(DeltaTime, ViewRotation, DeltaRot);
}
AActor* ViewTarget = GetViewTarget();
if (!PlayerCameraManager || !ViewTarget || !ViewTarget->HasActiveCameraComponent() || ViewTarget->HasActivePawnControlCameraComponent())
{
if (IsLocalPlayerController() && GEngine->XRSystem.IsValid() && GetWorld() != nullptr && GEngine->XRSystem->IsHeadTrackingAllowedForWorld(*GetWorld()))
{
auto XRCamera = GEngine->XRSystem->GetXRCamera();
if (XRCamera.IsValid())
{
XRCamera->ApplyHMDRotation(this, ViewRotation);
}
}
}
SetControlRotation(ViewRotation);
APawn* const P = GetPawnOrSpectator();
if (P)
{
P->FaceRotation(ViewRotation, DeltaTime);
}
}
로테이션 인풋은 DeltaRot 구축에 사용되고
ViewRotation이라는 값에 델타 로테이션이 활용됨
해당값은 SetControlRotation 함수에 넣어서 최종 Control Rotation 속성을 지정한 새로운 로테이션으로 덮어씀
void AABCharacterPlayer::Move(const FInputActionValue& Value)
{
FVector2D MovementVector = Value.Get<FVector2D>();
const FRotator Rotation = Controller->GetControlRotation();
const FRotator YawRotation(0, Rotation.Yaw, 0);
const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
AddMovementInput(ForwardDirection, MovementVector.X);
AddMovementInput(RightDirection, MovementVector.Y);
}
무브 함수는 위에서 업데이트된 컨트롤 로테이션 값을 가져오고
해당 로테이션을 기점으로 전진 방향과 오른쪽 방향을 얻어오고, 캐릭터를 이동시킴
~ 누르고 위 커맨드 입력
Look 함수의 인풋으로 저게 변함
* 좌우로 움직이면 Yaw가, 위아래는 Pitch가 바뀜
저상태에서 움직이면 ControlRotation의 값을 가져와서 이동
폰의 컨트롤 옵션
- Use Control Rotation (Yaw / Roll / Pitch)
- 컨트롤러에 지정된 Control Rotation 값에 폰의 Rotation을 맞출 것인가?
- 옵션 키면 폰의 회전은 컨트롤러의 Control Rotation과 동기화
스프링암의 컨트롤 옵션
스프링암의 컨트롤 옵션
- Use Pawn Control Rotation : 폰의 컨트롤 회전(Controller의 Control Rotation)을 사용할 것인가?
- Inherit (Yaw / Pitch / Roll) : 부모 컴포넌트(주로 루트컴포넌트)의 회전을 그대로 따를 것인가?
- Do Collision Test : 스프링암 중간에 장애물이 있으면 앞으로 당길 것인가? (Camera라는 트레이스 채널 사용)
체크되어 있어서 마우스 움직이니 스프링암이 같이 회전
- 3인칭
카메라 컨트롤 옵션
- Use Pawn Control Rotation
- 스프링암에 달려있다면 스프링암의 회전과 함께 고려
- 1인칭 카메라 회전
캐릭터 무브먼트의 이동 옵션
- Movement Mode : None, Walking, Falling ..
- 땅 위에 있으면 Walking
- 땅 위에 없으면 Failling
- 이동 기능을 끄고 싶으면 None 모드
- 이동 모드에서의 이동 수치 : MaxWalkSpeed
- 폴링 모드에서의 점프 수치 : JumpZVelocity
캐릭터 무브먼트의 회전 옵션
- Rotation Rate : 회전 속도의 지정
- Use Controller Desired Rotation : 컨트롤 로테이션을 목표 회전으로 잡고 지정한 속도로 돌리기
- Orient Rotation To Movement : 캐릭터 이동 방향에 회전을 일치시키기
- 폰의 회전 옵션과 충돌이 나지 않도록 주의
데이터 애셋
- UDataAsset 을 상속받은 언리얼 오브젝트 클래스
- 에디터에서 애셋 형태로 편리하게 데이터 관리 가능
- 캐릭터 컨트롤에 관련된 주요 옵션을 모아 애셋으로 관리
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Engine/DataAsset.h"
#include "ABCharacterControlData.generated.h"
/**
*
*/
UCLASS()
class ARENABATTLE_API UABCharacterControlData : public UPrimaryDataAsset
{
GENERATED_BODY()
public:
UABCharacterControlData();
UPROPERTY(EditAnywhere, Category = Pawn)
uint32 bUseControllerRotationYaw : 1;
UPROPERTY(EditAnywhere, Category = CharacterMovement)
uint32 bOrientRotationToMovement : 1;
UPROPERTY(EditAnywhere, Category = CharacterMovement)
uint32 bUseControllerDesiredRotation : 1;
UPROPERTY(EditAnywhere, Category = CharacterMovement)
FRotator RotationRate;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input)
TObjectPtr<class UInputMappingContext> InputMappingContext;
UPROPERTY(EditAnywhere, Category = SpringArm)
float TargetArmLength;
UPROPERTY(EditAnywhere, Category = SpringArm)
FRotator RelativeRotation;
UPROPERTY(EditAnywhere, Category = SpringArm)
uint32 bUsePawnControlRotation : 1;
UPROPERTY(EditAnywhere, Category = SpringArm)
uint32 bInheritPitch : 1;
UPROPERTY(EditAnywhere, Category = SpringArm)
uint32 bInheritYaw : 1;
UPROPERTY(EditAnywhere, Category = SpringArm)
uint32 bInheritRoll : 1;
UPROPERTY(EditAnywhere, Category = SpringArm)
uint32 bDoCollisionTest : 1;
};
UPROPERTY(EditAnywhere, Category = Pawn)
uint32 bUseControllerRotationYaw : 1;
- 캐릭터는 보통 Contoller Rotation은 Yaw만 씀
UPROPERTY(EditAnywhere, Category = CharacterMovement)
uint32 bOrientRotationToMovement : 1;
UPROPERTY(EditAnywhere, Category = CharacterMovement)
uint32 bUseControllerDesiredRotation : 1;
UPROPERTY(EditAnywhere, Category = CharacterMovement)
FRotator RotationRate;
- 무브먼트에서 사용하는 변수
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input)
TObjectPtr<class UInputMappingContext> InputMappingContext;
- 입력 매핑 컨텍스트를 담을 멤버변수 선언
UPROPERTY(EditAnywhere, Category = SpringArm)
float TargetArmLength;
UPROPERTY(EditAnywhere, Category = SpringArm)
FRotator RelativeRotation;
UPROPERTY(EditAnywhere, Category = SpringArm)
uint32 bUsePawnControlRotation : 1;
UPROPERTY(EditAnywhere, Category = SpringArm)
uint32 bInheritPitch : 1;
UPROPERTY(EditAnywhere, Category = SpringArm)
uint32 bInheritYaw : 1;
UPROPERTY(EditAnywhere, Category = SpringArm)
uint32 bInheritRoll : 1;
UPROPERTY(EditAnywhere, Category = SpringArm)
uint32 bDoCollisionTest : 1;
- 스프링암 관련
// Fill out your copyright notice in the Description page of Project Settings.
#include "Character/ABCharacterControlData.h"
UABCharacterControlData::UABCharacterControlData()
{
TargetArmLength = 400.0f;
}
타겟 암 렝스만 기본값을 줌
이제 데이터 애셋 만들 수 있음
데이터 애셋의 관리
두가지의 컨트롤 모드를 제공
- 현재 구현된 컨트롤 모드 : 3인칭 숄더뷰
- 추가로 구현할 컨트롤 모드 : 3인칭 쿼터뷰
입력키 V를 통해 컨트롤 설정을 변경
ENUM을 통해 두 개의 컨트롤 데이터 관리
-> 이를 위해 컨트롤 관리자 자료구조를 만들 것
데이터 애셋의 구성과 적용
각 섹션별로 데이터를 저장
- Pawn 카테고리
- CharacterMovement 카테고리
- 인풋 카테고리
- 스프링암 카테고리
Pawn과 캐릭터 무브먼트 데이터는 CharacterBase에서 설정
입력과 스프링암 데이터는 CharacterPlayer에서 설정
뷰의 변환
컨트롤을 변경할 때 서로 다른 입력 매핑 컨택스트를 지정
숄더뷰: ShoulderMove와 ShoulderLook 사용
쿼터뷰: QuaterMove만 사용
입력 액션을 사용해 변경
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "ABCharacterBase.generated.h"
UENUM()
enum class ECharacterControlType : uint8
{
Shoulder,
Quater
};
UCLASS()
class ARENABATTLE_API AABCharacterBase : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
AABCharacterBase();
virtual void SetCharacterControlData(const class UABCharacterControlData* CharacterControlData);
UPROPERTY(EditAnywhere, Category = CharacterControl, Meta = (AllowPrivateAccess = "true"))
TMap<ECharacterControlType, class UABCharacterControlData*> CharacterControlManager;
};
캐릭터 베이스 헤더
// Fill out your copyright notice in the Description page of Project Settings.
#include "Character/ABCharacterBase.h"
#include "Components/CapsuleComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "ABCharacterControlData.h"
// Sets default values
AABCharacterBase::AABCharacterBase()
{
// Pawn rotation
bUseControllerRotationPitch = false;
bUseControllerRotationYaw = false;
bUseControllerRotationRoll = false;
// Capsule
GetCapsuleComponent()->InitCapsuleSize(42.0f, 96.0f);
GetCapsuleComponent()->SetCollisionProfileName(TEXT("Pawn"));
// Movement
GetCharacterMovement()->bOrientRotationToMovement = true;
GetCharacterMovement()->RotationRate = FRotator(0.0f, 500.0f, 0.0f);
GetCharacterMovement()->JumpZVelocity = 700.0f;
GetCharacterMovement()->AirControl = 0.35f;
GetCharacterMovement()->MaxWalkSpeed = 500.0f;
GetCharacterMovement()->MinAnalogWalkSpeed = 20.0f;
GetCharacterMovement()->BrakingDecelerationWalking = 2000.0f;
// Mesh
GetMesh()->SetRelativeLocationAndRotation(FVector(0.0f, 0.0f, -100.0f), FRotator(0.0f, -90.0f, 0.0f));
GetMesh()->SetAnimationMode(EAnimationMode::AnimationBlueprint);
GetMesh()->SetCollisionProfileName(TEXT("CharacterMesh"));
static ConstructorHelpers::FObjectFinder<USkeletalMesh> CharacterMeshRef(TEXT("/Script/Engine.SkeletalMesh'/Game/Characters/Mannequins/Meshes/SKM_Quinn_Simple.SKM_Quinn_Simple'"));
if (CharacterMeshRef.Object)
{
GetMesh()->SetSkeletalMesh(CharacterMeshRef.Object);
}
static ConstructorHelpers::FClassFinder<UAnimInstance> AnimInstanceClassRef(TEXT("/Game/Characters/Mannequins/Animations/ABP_Quinn.ABP_Quinn_C"));
if (AnimInstanceClassRef.Class)
{
GetMesh()->SetAnimInstanceClass(AnimInstanceClassRef.Class);
}
static ConstructorHelpers::FObjectFinder<UABCharacterControlData> ShoulderObjectRef(TEXT("/Script/ArenaBattle.ABCharacterControlData'/Game/ArenaBattle/CharcaterControl/ABC_Shoulder.ABC_Shoulder'"));
if (ShoulderObjectRef.Object)
{
CharacterControlManager.Add(ECharacterControlType::Shoulder, ShoulderObjectRef.Object);
}
static ConstructorHelpers::FObjectFinder<UABCharacterControlData> QueterObjectRef(TEXT("/Script/ArenaBattle.ABCharacterControlData'/Game/ArenaBattle/CharcaterControl/ABC_Quater.ABC_Quater'"));
if (QueterObjectRef.Object)
{
CharacterControlManager.Add(ECharacterControlType::Quater, QueterObjectRef.Object);
}
}
void AABCharacterBase::SetCharacterControlData(const UABCharacterControlData* CharacterControlData)
{
// Pawn
bUseControllerRotationYaw = CharacterControlData->bUseControllerRotationYaw;
// CharacterMovement
GetCharacterMovement()->bOrientRotationToMovement = CharacterControlData->bOrientRotationToMovement;
GetCharacterMovement()->bUseControllerDesiredRotation = CharacterControlData->bUseControllerDesiredRotation;
GetCharacterMovement()->RotationRate = CharacterControlData->RotationRate;
}
캐릭터 베이스 구현
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Character/ABCharacterBase.h"
#include "InputActionValue.h"
#include "ABCharacterPlayer.generated.h"
/**
*
*/
UCLASS()
class ARENABATTLE_API AABCharacterPlayer : public AABCharacterBase
{
GENERATED_BODY()
public:
AABCharacterPlayer();
protected:
virtual void BeginPlay() override;
public:
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
// Character Controll Section
protected:
void ChangeCharacterControl();
void SetCharacterControl(ECharacterControlType NewCharacterControlType);
virtual void SetCharacterControlData(const class UABCharacterControlData* CharacterControlData);
// Camera Section
protected:
// Meta 설정 .. Private로 설정된 객체들을 블루프린트에서 접근할 수 있도록 함
// 스프링 암 == 카메라 지지대
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, Meta = (AllowPrivateAccess = "true"))
TObjectPtr<class USpringArmComponent> CameraBoom;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, Meta = (AllowPrivateAccess = "true"))
TObjectPtr<class UCameraComponent> FollowCamera;
// Input Section
protected:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, Meta = (AllowPrivateAccess = "true"))
TObjectPtr<class UInputAction> JumpAction;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, Meta = (AllowPrivateAccess = "true"))
TObjectPtr<class UInputAction> ChangeControlAction;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, Meta = (AllowPrivateAccess = "true"))
TObjectPtr<class UInputAction> ShoulderMoveAction;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, Meta = (AllowPrivateAccess = "true"))
TObjectPtr<class UInputAction> ShoulderLookAction;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, Meta = (AllowPrivateAccess = "true"))
TObjectPtr<class UInputAction> QuaterMoveAction;
void ShoulderMove(const FInputActionValue& Value);
void ShoulderLook(const FInputActionValue& Value);
void QuaterMove(const FInputActionValue& Value);
ECharacterControlType CurrentCharacterControlType;
};
캐릭터 플레이어 헤더
// Fill out your copyright notice in the Description page of Project Settings.
#include "Character/ABCharacterPlayer.h"
#include "Camera/CameraComponent.h"
#include "GameFramework/SpringArmComponent.h"
#include "InputMappingContext.h"
#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"
#include "ABCharacterControlData.h"
AABCharacterPlayer::AABCharacterPlayer()
{
// Camera
CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
CameraBoom->SetupAttachment(RootComponent);
CameraBoom->TargetArmLength = 400.0f;
CameraBoom->bUsePawnControlRotation = true;
FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));
// 소켓 지정자 사용하면 스프링 암 끝에 알아서 붙음
FollowCamera->SetupAttachment(CameraBoom, USpringArmComponent::SocketName);
FollowCamera->bUsePawnControlRotation = false;
// Input
static ConstructorHelpers::FObjectFinder<UInputAction> InputActionJumpRef(TEXT("/Script/EnhancedInput.InputAction'/Game/ArenaBattle/Input/Actions/IA_Jump.IA_Jump'"));
if (nullptr != InputActionJumpRef.Object)
{
JumpAction = InputActionJumpRef.Object;
}
static ConstructorHelpers::FObjectFinder<UInputAction> InputChangeActionControlRef(TEXT("/Script/EnhancedInput.InputAction'/Game/ArenaBattle/Input/Actions/IA_ChangeControl.IA_ChangeControl'"));
if (nullptr != InputChangeActionControlRef.Object)
{
ChangeControlAction = InputChangeActionControlRef.Object;
}
static ConstructorHelpers::FObjectFinder<UInputAction> InputActionShoulderMoveRef(TEXT("/Script/EnhancedInput.InputAction'/Game/ArenaBattle/Input/Actions/IA_ShoulderMove.IA_ShoulderMove'"));
if (nullptr != InputActionShoulderMoveRef.Object)
{
ShoulderMoveAction = InputActionShoulderMoveRef.Object;
}
static ConstructorHelpers::FObjectFinder<UInputAction> InputActionShoulderLookRef(TEXT("/Script/EnhancedInput.InputAction'/Game/ArenaBattle/Input/Actions/IA_ShoulderLook.IA_ShoulderLook'"));
if (nullptr != InputActionShoulderLookRef.Object)
{
ShoulderLookAction = InputActionShoulderLookRef.Object;
}
static ConstructorHelpers::FObjectFinder<UInputAction> InputActionQuaterMoveRef(TEXT("/Script/EnhancedInput.InputAction'/Game/ArenaBattle/Input/Actions/IA_QuaterMove.IA_QuaterMove'"));
if (nullptr != InputActionQuaterMoveRef.Object)
{
QuaterMoveAction = InputActionQuaterMoveRef.Object;
}
CurrentCharacterControlType = ECharacterControlType::Quater;
}
void AABCharacterPlayer::BeginPlay()
{
Super::BeginPlay();
SetCharacterControl(CurrentCharacterControlType);
}
void AABCharacterPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
// EnhancedInputComponent를 사용하지 않은 경우가 있을 수 있어 CastChecked
UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent);
EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Triggered, this, &ACharacter::Jump);
EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Completed, this, &ACharacter::StopJumping);
EnhancedInputComponent->BindAction(ChangeControlAction, ETriggerEvent::Triggered, this, &AABCharacterPlayer::ChangeCharacterControl);
EnhancedInputComponent->BindAction(ShoulderMoveAction, ETriggerEvent::Triggered, this, &AABCharacterPlayer::ShoulderMove);
EnhancedInputComponent->BindAction(ShoulderLookAction, ETriggerEvent::Triggered, this, &AABCharacterPlayer::ShoulderLook);
EnhancedInputComponent->BindAction(QuaterMoveAction, ETriggerEvent::Triggered, this, &AABCharacterPlayer::QuaterMove);
}
void AABCharacterPlayer::ChangeCharacterControl()
{
if (CurrentCharacterControlType == ECharacterControlType::Quater)
{
SetCharacterControl(ECharacterControlType::Shoulder);
}
else if (CurrentCharacterControlType == ECharacterControlType::Shoulder)
{
SetCharacterControl(ECharacterControlType::Quater);
}
}
void AABCharacterPlayer::SetCharacterControl(ECharacterControlType NewCharacterControlType)
{
UABCharacterControlData* NewCharacterControl = CharacterControlManager[NewCharacterControlType];
check(NewCharacterControl);
SetCharacterControlData(NewCharacterControl);
APlayerController* PlayerController = CastChecked<APlayerController>(GetController());
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
{
Subsystem->ClearAllMappings();
UInputMappingContext* NewMappingContext = NewCharacterControl->InputMappingContext;
if (NewMappingContext)
{
Subsystem->AddMappingContext(NewMappingContext, 0);
}
}
CurrentCharacterControlType = NewCharacterControlType;
}
void AABCharacterPlayer::SetCharacterControlData(const UABCharacterControlData* CharacterControlData)
{
Super::SetCharacterControlData(CharacterControlData);
CameraBoom->TargetArmLength = CharacterControlData->TargetArmLength;
CameraBoom->SetRelativeRotation(CharacterControlData->RelativeRotation);
CameraBoom->bUsePawnControlRotation = CharacterControlData->bUsePawnControlRotation;
CameraBoom->bInheritPitch = CharacterControlData->bInheritPitch;
CameraBoom->bInheritYaw = CharacterControlData->bInheritYaw;
CameraBoom->bInheritRoll = CharacterControlData->bInheritRoll;
CameraBoom->bDoCollisionTest = CharacterControlData->bDoCollisionTest;
}
void AABCharacterPlayer::ShoulderMove(const FInputActionValue& Value)
{
FVector2D MovementVector = Value.Get<FVector2D>();
const FRotator Rotation = Controller->GetControlRotation();
const FRotator YawRotation(0, Rotation.Yaw, 0);
const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
AddMovementInput(ForwardDirection, MovementVector.X);
AddMovementInput(RightDirection, MovementVector.Y);
}
void AABCharacterPlayer::ShoulderLook(const FInputActionValue& Value)
{
FVector2D LookAxisVector = Value.Get<FVector2D>();
AddControllerYawInput(LookAxisVector.X);
AddControllerPitchInput(LookAxisVector.Y);
}
void AABCharacterPlayer::QuaterMove(const FInputActionValue& Value)
{
FVector2D MovementVector = Value.Get<FVector2D>();
float InputSizeSquared = MovementVector.SquaredLength();
float MovementVectorSize = 1.0f;
float MovementVectorSizeSquared = MovementVector.SquaredLength();
if (MovementVectorSizeSquared > 1.0f)
{
MovementVector.Normalize();
MovementVectorSizeSquared = 1.0f;
}
else
{
MovementVectorSize = FMath::Sqrt(MovementVectorSizeSquared);
}
FVector MoveDirection = FVector(MovementVector.X, MovementVector.Y, 0.0f);
GetController()->SetControlRotation(FRotationMatrix::MakeFromX(MoveDirection).Rotator());
AddMovementInput(MoveDirection, MovementVectorSize);
}
캐릭터 플레이어 구현
인풋 매핑 컨텍스트 -> 직접 받는 입력이랑, 각 입력이랑 어떤 액션이 반응하는지 설정
각 액션은 SetupPlayerInputComponent에서 함수와 연결됨
SetCharacterControlData에서 데이터 애셋에서 데이터 불러들임
(* Base에선 폰이랑 캐릭터 무브먼트만 설정, 아래에서 카메라랑 인풋 설정)
전환 잘 됨
'언리얼 엔진 > Unreal Game Framework' 카테고리의 다른 글
[UE Game Framework] #6 Character Attack Hit Check (0) | 2025.01.05 |
---|---|
[UE Game Framework] #5 Character Combo Action (0) | 2025.01.04 |
[UE Game Framework] #4 Character Animation Setting (0) | 2025.01.04 |
[UE Game Framework] #2 Character & Input System (0) | 2025.01.03 |
[UE Game Framework] #1 기초 (0) | 2025.01.02 |