UDataAsset을 상속받은 언리얼 오브젝트 클래스이다.
에디터에서 애셋 형태로 편리하게 데이터를 관리할 수 있는 장점이 있다!!.
캐릭터 컨트롤에 관련된 주요 옵션을 모아 애셋으로 관리 한다


데이터 애셋 테스트하면서 정리.
두 가지의 컨트롤 모드를 제공
현재 구현된 컨트롤 모드 : 3인칭 솔더뷰
추가로 구현할 컨트롤 모드 : 3인칭 쿼터뷰
입력키 V를 통해 컨트롤 설정을 변경
ENUM을 통해 두 개의 컨트롤 데이터를 관리

데이터 애셋의 구성과 적용
각 섹션별로 데이터를 저장
- Pawn 카테고리
- 캐릭터무브먼트 카테고리
- 입력 카테고리
- 스프링암 카테고리
Pawn과 캐릭터무브먼트 데이터는 CharacterBase에서 설정
입력과 스프링암 데이터는 CharacterPlayer에서 설정

<코드 예시>UABCharacterControlData클래스 만들기
// 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 ARENABATTLEDEMO_API UABCharacterControlData : public UPrimaryDataAsset
{
GENERATED_BODY()
public:
//기본값 설정을 위해서.
UABCharacterControlData();
UPROPERTY(EditAnywhere, Category = Pawn)
uint8 bUseControllerRotationYaw : 1;
UPROPERTY(EditAnywhere, Category = CharacterMovement)
uint8 bOrientRotationToMovement : 1;
UPROPERTY(EditAnywhere, Category = CharacterMovement)
uint8 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)
uint8 bUsePawnControlRotation : 1;
UPROPERTY(EditAnywhere, Category = SpringArm)
uint8 bInheritPitch : 1;
UPROPERTY(EditAnywhere, Category = SpringArm)
uint8 bInheritYaw : 1;
UPROPERTY(EditAnywhere, Category = SpringArm)
uint8 bInheritRoll : 1;
UPROPERTY(EditAnywhere, Category = SpringArm)
uint8 bDoCollisionTest : 1;
};
<cpp>
// Fill out your copyright notice in the Description page of Project Settings.
#include "Character/ABCharacterControlData.h"
UABCharacterControlData::UABCharacterControlData()
{
TargetArmLength = 500.0f;
}
데이터 에셋 생성

데이터 에셋 데이터 셋팅

Shoulder와 Quater때의 Move함수 코드 분리
void AABCharacterPlayer::QuarterMove(const FInputActionValue& Value)
{
// 입력 값 읽기.
FVector2D Movement = Value.Get<FVector2D>();
float MovementVectorSize;
float MovementVectorSizeSquared = Movement.SizeSquared();
// 두 방향으로 입력이 들어오면, 이동 방향은 정규화해 크기를 1로 만들고,
// 입력 스케일을 1로 강제 설정.
if (MovementVectorSizeSquared > 1.0f)
{
Movement.Normalize();
MovementVectorSize = 1.0f;
}
// 입력이 1이하이면, 해당 입력을 스케일로 사용하기 위해 값 계산.
else
{
MovementVectorSize = FMath::Sqrt(MovementVectorSizeSquared);
}
FVector MoveDirection = FVector(Movement.X, Movement.Y, 0.0f);
//캐릭터가 이동하는 방향에 맞게 컨트롤러 회전 설정.
Controller->SetControlRotation(FRotationMatrix::MakeFromX(MoveDirection).Rotator());
// 입력에 따른 방향으로 이동하도록 입력 전달.
AddMovementInput(MoveDirection, MovementVectorSize);
}
void AABCharacterPlayer::ShoulderMove(const FInputActionValue& Value)
{
//입력값 읽기.
FVector2D Movement = Value.Get<FVector2D>();
//컨트롤러의 회전 값.
FRotator Rotation = GetControlRotation();
FRotator YawRotation(0.0f, Rotation.Yaw, 0.0f);
//방향 구하기.
FVector ForwardVector = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
FVector RightVector = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
//무브먼트 컴ㅍ포넌트에 값 전달.
AddMovementInput(ForwardVector, Movement.X);
AddMovementInput(RightVector, Movement.Y);
}
키입력시 호출 함수 바인딩
void AABCharacterPlayer::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
auto EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent);
//Binding
EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Triggered, this, &ACharacter::Jump);
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(QuarterMoveAction, ETriggerEvent::Triggered, this, &AABCharacterPlayer::QuarterMove);
}
컨트롤 변경 함수
void AABCharacterPlayer::ChangeCharacterControl()
{
//사용할 캐릭터 컨트롤을 변경하는 함수.
if (CurrentCharacterControlType == ECharacterControlType::Quarter)
{
SetCharacterControl(ECharacterControlType::Shoulder);
}
else if (CurrentCharacterControlType == ECharacterControlType::Shoulder)
{
SetCharacterControl(ECharacterControlType::Quarter);
}
}
해당 컨트롤러 셋팅
void AABCharacterPlayer::SetCharacterControl(ECharacterControlType NewCharacterControlType)
{
// 변경할 컨트롤 타입에 대응하는 데이터 애셋 로드(TMap으로부터).
UABCharacterControlData* NewCharacterControl = CharacterControlManager[NewCharacterControlType];
check(NewCharacterControl);
// 데이터 애셋을 사용해 관련 값 설정.
SetCharacterControlData(NewCharacterControl);
// Add InputMapping Context to Enhanced Input System.
APlayerController* PlayerController = CastChecked<APlayerController>(GetController());
if (auto SubSystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
{
SubSystem->ClearAllMappings();
SubSystem->AddMappingContext(
NewCharacterControl->InputMappingContext,
0
);
}
// 현재 사용 중인 캐릭터 컨트롤 타입 업데이트.
CurrentCharacterControlType = NewCharacterControlType;
}
결과

'언리얼 엔진 공부 > 언리얼C++' 카테고리의 다른 글
| 캐릭터 공격 판정 (0) | 2025.04.18 |
|---|---|
| 캐릭터 애니메이션 시스템 (0) | 2025.04.14 |
| 언리얼 엔진 게임 제작 기초 (0) | 2025.04.10 |
| 어설션(Assertion) (0) | 2025.04.08 |
| 직렬화 (2) | 2025.04.08 |