언리얼 개인 프로젝트/언리얼엔진C++ 독학(이득우)

6.캐릭터 제작과 컨트롤_5)컨트롤 방식 변경

현구구 2022. 3. 5. 20:02

프로젝트 세팅>엔진-입력>액션 매핑에서 ViewChange 를 하나 만들고 키에는 Shift+v 를 입력한다

앞으로 Shift+v를 입력하면 GTA 모드와 DIABLO모드가 변경 될 것이다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<ABCharacter.h>
 
// Fill out your copyright notice in the Description page of Project Settings.
 
#pragma once
 
#include "ArenaBattle.h" // = EngineMinimal.h
#include "GameFramework/Character.h"
#include "ABCharacter.generated.h"
 
UCLASS()
class ARENABATTLE_API AABCharacter : public ACharacter
{
    ...
 
private:
    void UpDown(float NewAxisValue);
    void LeftRight(float NewAxisValue);
    void LookUp(float NewAxisValue);
    void Turn(float NewAxisValue);
 
    void ViewChange();//컨트롤방식을 변경하기 위한 함수
 
};
cs

ABCharacter.h 파일에서 컨트롤 방식을 변경해줄 함수 ViewChange를 선언해준다.

 

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
32
33
34
<AVCharacter.cpp>
#include "ABCharacter.h"
 
...
 
// Called to bind functionality to input
void AABCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
    Super::SetupPlayerInputComponent(PlayerInputComponent);
    //BeginPlay() 보다 먼저 실행되는 함수 결합할 때 사용
 
    PlayerInputComponent->BindAction(TEXT("ViewChange"), EInputEvent::IE_Pressed, this&AABCharacter::ViewChange);
 
    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::ViewChange()
{
    switch (CurrentControlMode)
    {
    case EControlMode::GTA:
        SetControlMode(EControlMode::DIABLO);
        break;
    case EControlMode::DIABLO:
        SetControlMode(EControlMode::GTA);
        break;
    }
    //GTA모드일대 쉬프트+V를 누르면 DIABLO로 반대일 땐 GTA로 게임모드 변경
}
 
cs

 

우선 SetupPlayerInputComponent에서 방금 만들어준 ViewChange 를 캐릭터에 묶어준다

그 다음으로 h파일에서 선언한 ViewChange함수를 정의해준다.

컴파일하고 게임을 실행해보면 Shift+V 를 누를때마다 게임모드가 변경되는걸 볼 수 있다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<ABCharacter.h>
// Fill out your copyright notice in the Description page of Project Settings.
 
#pragma once
 
#include "ArenaBattle.h" // = EngineMinimal.h
#include "GameFramework/Character.h"
#include "ABCharacter.generated.h"
 
UCLASS()
class ARENABATTLE_API AABCharacter : public ACharacter
{
    ...
 
protected:
    ...
 
    float ArmLengthTo = 0.0f; //컨트롤모드 변경시 화면변환을 부드럽게 해줄 변수들 
    FRotator ArmRotationTo = FRotator::ZeroRotator;
    float ArmLengthSpeed = 0.0f;
    float ArmRotationSpeed = 0.0f;
 
};
 
cs

 

이제 컨트롤 모드 간의 변환을 부드럽게 하기 위해 변수들을 선언한다

ArmLengthTo : 이 변수까지 도달하면 화면 이동이 멈춘다

ArmRotationTo : 이 좌표까지 도달하면 화면 회정이 멈춘다

ArmLegthSpeed : 모드 변환 중 화면이 이동하는 속도

ArmRotationSpeed : 모드 변환 중 화면이 회전하는 속도

 

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
<ABCharacter.cpp>
// Fill out your copyright notice in the Description page of Project Settings.
 
 
#include "ABCharacter.h"
 
// Sets default values
AABCharacter::AABCharacter()
{
     ...
 
    ArmLengthSpeed = 3.0f; //목표 ArmLength까지 이동하는 속도
    ArmRotationSpeed = 10.0f; //목표 ArmRotation까지 회전하는 속도
}
void AABCharacter::SetControlMode(EControlMode NewControlMode)
{
    CurrentControlMode = NewControlMode;
    switch(CurrentControlMode)
    {
    case EControlMode::GTA:
        //SpringArm->TargetArmLength = 450.0f; //현재 컨트롤 모드가 GTA일때 스프링암의 길이는 450
        //SpringArm->SetRelativeRotation(FRotator::ZeroRotator);
        ArmLengthTo = 450.0f;
        SpringArm->bUsePawnControlRotation = true;
        SpringArm->bInheritPitch = true;
        SpringArm->bInheritRoll= true;
        SpringArm->bInheritYaw = true;
        bUseControllerRotationYaw = false;
        GetCharacterMovement()->bOrientRotationToMovement = true;//방향에따른 움직임 설정(회전기능)
        GetCharacterMovement()->bUseControllerDesiredRotation = false;
        GetCharacterMovement()->RotationRate = FRotator(0.0f,720.0f,0.0f);//회전속도 설정해서 자연스러운 회전 움직임
        break;
    case EControlMode::DIABLO:
        //SpringArm->TargetArmLength = 800.0f;
        //SpringArm->SetRelativeRotation(FRotator(-45.0f,0.0f,0.0f));
        ArmLengthTo = 800.0f;
        ArmRotationTo = FRotator(-45.0f, 0.0f, 0.0f);
        SpringArm->bUsePawnControlRotation = false;//시점 고정
        SpringArm->bInheritPitch = false;
        SpringArm->bInheritRoll = false;
        SpringArm->bInheritYaw = false;
        SpringArm->bDoCollisionTest = false;
        bUseControllerRotationYaw = false;
        GetCharacterMovement()->bOrientRotationToMovement = false;
        GetCharacterMovement()->bUseControllerDesiredRotation = true;
        GetCharacterMovement()->RotationRate = FRotator(0.0f, 720.0f, 0.0f);
        break;
    }
}
 
// Called every frame
void AABCharacter::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);
    
    SpringArm->TargetArmLength = FMath::FInterpTo(SpringArm->TargetArmLength, ArmLengthTo, DeltaTime, ArmLengthSpeed);
 
    switch (CurrentControlMode)
    {
    case EControlMode::DIABLO:
        SpringArm->SetRelativeRotation(FMath::RInterpTo(SpringArm->GetRelativeRotation(), ArmRotationTo, DeltaTime, ArmRotationSpeed));
        break;
    }
    ...
}
 
...
 
void AABCharacter::ViewChange()
{
    switch (CurrentControlMode)
    {
    case EControlMode::GTA:
        GetController()->SetControlRotation(GetActorRotation());
        SetControlMode(EControlMode::DIABLO);
        break;
    case EControlMode::DIABLO:
        GetController()->SetControlRotation(SpringArm->GetRelativeRotation());
        SetControlMode(EControlMode::GTA);
        break;
    }
    //GTA모드일대 쉬프트+V를 누르면 DIABLO로 반대일 땐 GTA로 게임모드 변경
}
 
cs

그리고  cpp 파일에서 코드들을 추가하면 다음과 같이 부드러운 화면전환을 볼 수 있다.