캐릭터가 사용하기 위한 무기를 구현하였다

클래스는 Actor로 상속을 받고 만들었으며 Item -> Weapon -> Katana 를 상속받는 클래스를 만들어주었다.

먼저 공통적으로 사용될 변수들을 Item에 적용시켜주며 Weapon에선 무기 공격력 등등 Katana에선 Katana만의 고유능력을 이용할 수게 만들어 주었다.

 

언리얼엔진에서 카타나클래스로 블루프린트를 만들어 준 후 스태틱메쉬를 입혀주었으며, 캐릭터에 착용할 수 있게

캐릭터 오른손에 무기소켓을 추가해주었다.

 

그다음 캐릭터에서 TSubclassOf를통해 카타나 클래스를 받아오고 이를 통해 BeginPlay함수에서 무기를 스폰해주고 무기의 AttachToComponent를 통해 WeaponSocket에 부착해 주었다.

 

이제 언리얼엔진에서 실행하게 되면 캐릭터가 무기를 들고있는 모습을 볼 수 있다.

먼저 AbilitySystem은 Tag를 이용해서 개체에 대해 식별, 분류, 일치 및 필터링하는데 사용하게 된다.

프로젝트 세팅 -> GameplayTags에 들어가 필요한 태그를 만들어서 세팅해준다.

 

태그를 만든 후 Input Action을 담을 DataAsset클래스를 만들어 준다.

 

언리얼 엔진 툴에서 입력 액션에 필요한 액션들을 만들고 컨텍스트에 추가해 준다.

 

언리얼 엔진 툴에서 방금 만든 Data Asset 클래스가 노출이 되며 이를 선택하여 만들어 준다.

그럼 TArray로 만든 AbilityInputActions가 있으며 이는 FBVInputAction 구조체이고 이를 설정해준다.

 

EnhancedInput 클래스를 만들어 주고 바인딩에 필요한 객체들을 받아오게 만들어 준다.

이때 Pressed, Released, Held 3개에 대해 키입력 함수를 받아오며 바인딩 시켜 준다.

 

이제 PlayerController로 돌아와 DataAsset을 넣을수 있는 변수와 Pressed, Released, Held 함수를 만들어 주고

SetupInputComponent에서 방금 만든 EnhancedInput의 AbilityBind함수를 호출 시켜준다.

마지막으로 프로젝트 세팅 -> 입력 에서 Default Classes에 기본 입력 컴포넌트 클래스를 방금만든 EnhancedInput클래스로 바꿔준다.

이제 실행해서 테스트를 해보면 1초정도 누르고 마우스를 때면 Pressed는 1번 Held는 누르고 있는동안 Released는 마우스를 땔때 잘 나오는걸 확인 할 수 있다.

이를 통해 Pressed, Released, Held 함수를 이용하여 알맞게 능력을 구한하면 될것 같다.

예를들면 Held에선 기를 모으는 능력을 구현한다 던지 Pressed는 기본공격 1회를 한다던지 하면 될것같다.

어트리뷰트에 세팅된 Health, Stamina를 UI에 연동시켜 만들어보았다.

먼저 게임에 보여질 메인화면에서 캐릭터 정보창을 만들어 본다.

밑에 그림은 게임시작시 UI가 만들어지는 순서이다.

먼저 HUD클래스를 상속받아 클래스를 만들어 준다.

 

그다음 캐릭터에 BeginPlay()에서 컨트롤러를 통해 CreateHUDWidget() 함수를 실행시켜준다.

 

이때 컨트롤러의 CreateHUDWidget함수는 존재하지않기 때문에 컨트롤러에서 함수를 만들어준다.

 

그다음 만들어준 HUD 클래스에서 필요한 변수와 함수를 만들어준다.

이때 변수는 TSubclassOf를 통해서 외부로부터 클래스를 가져오게 만들어준다. 

 

이때 메인화면의 게임위젯이 필요로 하기때문에 위젯 클래스를 만들어 주고 필요한 변수와 함수를 만들어준다.

 

위의 그림에서 CharacterStatusWidget이라는 클래스를 필요로 하기때문에 CharacterStatusWidget클래스를 만들어 준다.

 

또다시 위의 그림에서 HealthBarWidget과 StaminaBarWidget이 필요로 하기때문에 각각 클래스를 만들어 준다.

 

이때 만들어진 위젯클래스에서 UPROPERTY에서 meta = (BindWidget)을 사용한 변수가 있는데 이는 블루프린트 위젯의 계층구조에서 존재하는 이름과 일치해야 사용할 수 있다게된다. 그래서 meta = (BindWidget)을 사용한 변수의 이름과 위젯 계층구조에 존재하는 이름을 일치시켜 준다.

 

그다음 Attribute를 관리해주는 PlayerState 클레스 에서 능력치에 대한 Get함수와 Delegate를 통해 콜백함수를 만들어준다. 콜백함수를 등록시킬 함수에 FOnAttributeChangeData는 헤더파일에 GameplayEffectTypes.h를 추가시켜준다.

이제 컴파일 후 실행해보면 UI가 나오고 테스트용으로 MaxHealth를 바꿔주는 액터를 만들어 준다음 액터와 상호작용하면 잘 HealthBar와 Attribute의 있는 MaxHealth가 적용되는 것을 볼 수 있다.

 

어빌리티 시스템은 캐릭터의 기술, 능력치, 디버프 같은 것들을 유연하고 쉽게 구현해주는 프레임워크를 지원해준다.

또한 멀티플레이도 가능하게 해주며 멀티플레이에서 복잡한 시스템을 효율적으로 처리도 해준다.

 

어빌리티 시스템은 Gameplay Ability, Gameplay Tag, Attributes, Gameplay Effects  로 주를 이루게 된다.

 

Gameplay Ability 는 게임 내 어빌리티가 하는 일에 대해 알 수 있다.

언제 어떤 상황 에서 사용할 수 있는지 정의하며 게임내에 상호작용에 따른 작업을 실행 할 수 있다.

예로 쿨다운(재사용 대기시간) 및 시전 비용, 플레이어 입력, 애님 몽타주가 있는 애니메이션, 어빌리티 자체를 액터에 부여할 때의 반응도 구현할 수 있다.

 

Gameplay Tag 는 어빌리티의 상호작용 방식에 결정을 한다.

어빌리티의 작동방식에 따라 일정한 태그를 통해 식별하여 사용한다.

 

Attributes 는 캐릭터의 능력치를 가질 수 있다.

캐릭터의 공격력, 체력, 공격 속도, 점프 높이 등등 이를 가질 수 있으며 Gameplay Effects 를 통해 즉시 또는 일정 시간 동안 게임플레이에 능력치를 변경할 수 있다.

 

 GameplayEffects 는 Attributes 를 변경하기 위한 방편이다.

다양한 이펙트를 통해 체력을 영구적으로 증가시킨다 던지 공격 속도를 일시적으로 증가시켜준다던지

캐릭터의 상호작용을 통해 능력치를 변경할 수 있다.

 

제일 먼저 플러그인을 설정 해주어야 한다.

메뉴에서  편집 - > 플러그인 들어간 후 검색을 통해 Gameplay Abilites를 체크하고 재시작을 해준다.

 

어빌리티 시스템을 사용하기 위한 필요한 클래스들을 만들어준다.

AbilitySystemComponent, AttributeSet, GameplayAbility 이 3개를 만들어준다.

그리고 c++에서 사용할 수 있게 모듈 또한 추가해 준다.

지금 만들고자 하는게임은 싱글게임이지만 멀티플레이를 염두해 두고 만들면 좋을것 같아서 멀티플레이기반으로 만들어 볼려 한다. 포폴 및 게임은 혼자 공부할려고 만드는것 이기에 자세한 설명이나 이전 단계없이 진행을 하게 될것이다.

 

저는 일단 어빌리티 관련된건 PlayerState에서 관리해 줄려고 합니다. 일반적으로 PlayerState는 클라이언트의 정보를 관리 해주기도 하며 멀티플레이를 염두하여 공부하기 위해 PlayerState로 한다.

PlayerState클래스를 만들어주고 만들었던 게임모드에서 PlayerState를 설정 해준다.

 

PlayerState클래스에서 AbilitySystemComponent와 AttributeSet를 세팅해준다.

 

그다음 캐릭터베이스 클래스에서도 어빌리티 시스템을 세팅해준다.

 

이제 베이스를 상속받는 주인공캐릭터에 어빌리티 시스템을 세팅해준다.

 

지금 까지의 흐름은 게임시작시 PlayerState가 먼저 호출이 되어서 AbilitySystemComponent와 Attribute를 만들어주고

캐릭터에서 PossessedBy를 통해 PlayerState가져와 캐스팅 후 AbilitySystemComponent와 Attribute를 가져와 캐릭터에서도 사용 할수 있게 만들어 준다.

 

이제 Atrribute를 설정해 준다.

캐릭터의 능력치는 FGameplayAttributeData로 관리를 하며 UPROPERTY에서 OnRep_XXX를 통해 콜백함수를 등록시켜준다.

그리고 GetLifetimeReplicatedProps함수를 통해 복제된 변수를 등록하고 이 등록된 변수의 상태를 바꿀수 있다.

이는 REPNOTIFY_Always, REPNOTIFY_OnChanged 둘중 하나를 택하면 되며 저는 Always 항상이를 복제하게 설정했습니다.

 

컴파일 후 콘솔창에 showdebug abilitysystem을 쳐보면 적용된 어트리뷰트나 게임어빌리티 시스템에 관한 정보를 볼 수 있다.

오늘은 캐릭터의 애니메이션을 기본적인것 몇개를 추가해볼려합니다.

먼저 준비된 애니메이션이 있어야하는데 저는 마켓플레이스에서 구입한 애니메이션을 이용하여

리타겟을 해서 기본적인 움직이는 애니메이션을 준비했습니다.

 

먼저 AnimInstance가 필요한데 이는 애니메이션에 관한 기능들이 있는거 같다.

이를 통해 내가 필요한 기능을 추가적으로 넣으면서 만들어 주었다.

이제 내가만든 블루프린트 캐릭터에 세팅을 해주었다.

디테일창에 애니메이션 목록에 애님 클래스를 적용 시켜주었다.

 

이제 디버그를 통해 Speed가 출력이 잘 되는지 확인을 해주었다.

 

 

그리고 애님인스턴스 객체를 통해 블루프린트를 만들어 주었다

 

방금 만든 애님 블루프린트에서 AnimGraph에 스테이트 머신을 만들어주고 이름은 Locomotion이라 지어주었다.

 

Locomotion에서 State를 추가해주고 노드를 연결 시켜주었다.

 

Idle과 Run을 더블클릭하여 들어가서 애니메이션 출력포즈에 준비한 애니메이션을 가져와 연결시켜주었다.

 

여기서 Idle의 애님스퀀스와 Run의 애님시퀀스는 계속 동작 해야 하기때문에 스퀀스를 클릭하고

디테일창에 보면 애니메이션 루프를 체크해주는 란이 있는데 이를 체크해서 무한루프로 만들어 주었다.

 

Idle -> Run,  Run -> Idle 전환 해주는 트랜지션 룰을 만들어 주었다.

왼쪽 Idle -> Run        오른쪽 Run -> Idle

이제 마지막으로 애님 그래프 최상단으로 돌아와 Locomotion State를 Cached 화 해주고이를 출력포즈에 연결해주었다.

 

컴파일 후 레벨에서 플레이를 하게되면 idle포즈와 run포즈가 잘 작동하는걸 볼 수 있었다.

 

1. 캐릭터 만들기

2. 게임시작시 캐릭터 배치하기

3. 캐릭터 이동하기

4. 캐릭터 회전하기

 

 


 

먼저 캐릭터가 있어야하기때문에 메쉬를 구하였다.

메쉬는 에픽게임즈 샘플에 있는 Slay를 가져와서 사용하였다.

주인공캐릭터를 사용할 메쉬

 

이제 캐릭터를 만들기 위해 캐릭터 클래스를 만들어준다.

주인공 캐릭터와 적 캐릭터에 공통으로 쓸 수 있는 변수나 함수가 존재 할 것 같아서

CharacterBase로 부모클래스를 만들어주고 먼저 주인공인 Aiden캐릭터를 만들어주었다.

캐릭터 클래스의 구조

 

Aiden캐릭터 클래스를 만든 후 블루프린트로 생성하고 메쉬를 설정해주었다.

이때 위치와 회전이 안맞어서 적절하게 세팅을 해주었다.

초기 메쉬를 설정했을때 높이와 회전이 이상하여 적절하게 바꿔준다.

 

레벨에서 월드 설정을 통해 게임모드를 설정 할 수 있다.

게임모드를 통해 기본 폰 클래스와 컨트롤러 등등을 설정 할 수 있다.

C++클래스를 만들어 주고 이를 블루프린트를 만들어 주며 캐릭터를 Aiden캐릭터로 설정을 해 주었다.

블루프린트 게임모드 베이스에서 디폴트 폰 세팅

 

그리고 나서 월드 세팅에 게임모드를 오버라이드 할 수 있는데 이때 방금만든 게임모드를 지정해주었다.

월드 세팅에서 게임 모드를 오버라이드를 통해 원하는 게임모드로 지정

 

그다음 카메라를 세팅을 해준다.

캐릭터 클래스로 들어가 CameraComponent와 SpringArmComponent를 달아주고 이를 생성자에서 세팅해주었다.

자잘한 조절은 블루프린트에서 직접 조절해주고 레벨을 플레이하면 캐릭터의 뒷모습을 볼 수 있게 된다.

 

캐릭터를 움직일 수 있도록 향상된 입력을 통해 세팅을 해주었다.

PlayerController클래스를 만들고 컨트롤러에서 입력제어를 해주었다.

제일 먼저 향상된 입력 시스템을 코드에서 사용하기 위해 모듈을 추가해준다.

xxx.Build.cs 에 추가 해줄 수 있다.

모듈을 추가해 준다.

그다음 플레이어 클래스에서 향상된 입력에 관한 코드를 작성 하였다.

 

이제 언리얼 메인화면으로 돌아가서 입력 액션에 관한 블루프린트를 만들어 준다.

 

입력 액션에선 값 타입을 Vector2D로 바꿔준다

입력 액션 디테일 창

 

입력 매핑 컨텍스트에선 매핑을 위에 만든 입력 액션을 선택 해주고

키보드 wsad 를 각각 알맞에 세팅을 해주었다.

입력 컨텍스트 디테일 창

 

그다음 PlayerController를 블루프린트로 만든 후 입력 액션과 입력 컨텍스트를 선택해 주었다.

BP_AidenPlayerController 디테일 창

 

마지막으로 게임모드에서 PlayerController를 방금만든 블루프린트 PlayerController로 지정해주었다.

 

이제 레벨에서 플레이를 하고 wsad를 누르게되면 움직이는걸 볼 수 있다.

wsad로 움직이는 영상

이번엔 캐릭터를 회전하게 만들어 준다.

다시 입력 액션을 만들어 준다 이번엔 IA_Look이라고 만들어주었다 세팅은 Vector2D로 하였다.

 

입력 컨텍스트에선 마우스 XY 2D축으로 바꿔주고 모디파이어를 반대로 부정으로 바꾼다음 Y축만 체크해준다.

 

다시 PlayerController 클래스로 와서 코드를 작성 해준다.

 

컴파일 후 PlayerController블루프린트로 돌아와서 LookAction을 추가해준다.

 

마지막으로 캐릭터 클래스에서 추가적인 세팅을 해준다.

 

이제 움직이고 마우스를 통해 회전을 할 수 있게 됬다.

+ Recent posts