// ABCharacter.h
UCLASS()
class ARENABATTLE_API AABCharacter : public ACharacter
{
	GENERATED_BODY()

public:
	// Sets default values for this character's properties
	AABCharacter();

protected:
	...

	float ArmLengthTo;
	FRotator ArmRotationTo;
	float ArmLengthSpeed;
	float ArmRotationSpeed;
public:	
	...

	UPROPERTY(VisibleAnywhere, Category = Camera)
	USpringArmComponent* SpringArm;

	UPROPERTY(VisibleAnywhere, Category = Movement)
	UCameraComponent* Camera;
    
    ...

private:
	virtual void Jump() override;
	void UpDown(float NewAxisValue);
	void LeftRight(float NewAxisValue);
	void LookUp(float NewAxisValue);
	void Turn(float NewAxisValue);
    
	...

};
// ABCharacter.cpp

// 생성자
AABCharacter::AABCharacter()
	: ArmLengthTo(0.0f)
	, ArmRotationTo(FRotator::ZeroRotator)
	, ArmLengthSpeed(0.0f)
	, ArmRotationSpeed(0.0f)
{
    // 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;

    //카메라 관련 컴포넌트 가져오기
    SpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("SPRINGARM"));
    Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("CAMERA"));

    ...

    //SpringArm은 캐릭터에 붙이고, 카메라는 SpringArm에 붙착 돼서 SpringArm의 움직임을 기준으로 카메라가 비추게 된다.
    SpringArm->SetupAttachment(GetCapsuleComponent());
    Camera->SetupAttachment(SpringArm);

    ...

    //SpringArm 길이, 위치 설정
    SpringArm->TargetArmLength = 400.0f;
    SpringArm->SetRelativeRotation(FRotator(-15.0f, 0.0f, 0.0f));

    ...
    //3인칭 카메라 모드 설정(GTA 카메라 시점)
    SetControlMode(EControlMode::GTA);
    //SpringArm 속도 설정
    ArmLengthSpeed = 3.0f;
    ArmRotationSpeed = 10.0f;

    //캐릭터 점프력 설정
    GetCharacterMovement()->JumpZVelocity = 400.0f;

    ...
}

// Called to bind functionality to input
void AABCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
    Super::SetupPlayerInputComponent(PlayerInputComponent);

    PlayerInputComponent->BindAction(TEXT("Jump"), EInputEvent::IE_Pressed, this, &AABCharacter::Jump);
    PlayerInputComponent->BindAxis(TEXT("UpDown"), this, &AABCharacter::UpDown);
    PlayerInputComponent->BindAxis(TEXT("LeftRight"), this, &AABCharacter::LeftRight);
    PlayerInputComponent->BindAxis(TEXT("LookUp"), this, &AABCharacter::LookUp);
    PlayerInputComponent->BindAxis(TEXT("Turn"), this, &AABCharacter::Turn);
}


void AABCharacter::SetControlMode(EControlMode ControlMode)
{
    UCharacterMovementComponent& CharacterMovement = *GetCharacterMovement();

    ArmLengthTo = 450.0f;
    SpringArm->bUsePawnControlRotation = true;
    SpringArm->bInheritPitch = true;
    SpringArm->bInheritRoll = true;
    SpringArm->bInheritYaw = true;
    SpringArm->bDoCollisionTest = true;
    bUseControllerRotationYaw = false;
    CharacterMovement.bOrientRotationToMovement = true;
    CharacterMovement.bUseControllerDesiredRotation = false;
    CharacterMovement.RotationRate = FRotator(0.0f, 720.0f, 0.0f);
}

void AABCharacter::Jump()
{
    // 공격 모션중엔 점프를 못한다.
    if (IsAttacking == true)
   	 return;

    Super::Jump();
}

// SpringArm의 Rotation 값은 옵션에 의해 ControlRotation값과 동일하므로 ControlRoation 값이 곧 카메라가 바라보는 방향이다.
// ControlRotation의 값으로부터 회전 행렬을 생성 한 후, 원하는 방향 축을 대입해 캐릭터가 움직일 방향 값을 가져올 수 있다.
// 시선 방향 X축, 우측 방향 Y축
void AABCharacter::UpDown(float NewAsixValue)
{
    // 공격 모션중엔 움직이지 못한다.
    if (IsAttacking == true)
    	return;

    switch (CurrentControlMode)
    {
      case EControlMode::GTA:
      	AddMovementInput(FRotationMatrix(GetControlRotation()).GetUnitAxis(EAxis::X), NewAsixValue);
      	break;
    }
}

void AABCharacter::LeftRight(float NewAsixValue)
{
	// 공격 모션중엔 움직이지 못한다.
    if (IsAttacking == true)
    return;

    switch (CurrentControlMode)
    {
      case EControlMode::GTA:
      	AddMovementInput(FRotationMatrix(GetControlRotation()).GetUnitAxis(EAxis::Y), NewAsixValue);
      	break;
    }
}

void AABCharacter::LookUp(float NewAsixValue)
{
    switch (CurrentControlMode)
    {
      case EControlMode::GTA:
      	AddControllerPitchInput(NewAsixValue);
      	break;
    }
}

void AABCharacter::Turn(float NewAsixValue)
{
    switch (CurrentControlMode)
    {
    case EControlMode::GTA:
      AddControllerYawInput(NewAsixValue);
      break;
    }
}

+ Recent posts