Make Unreal REAL.
article thumbnail
Advanced Unreal Engine 5 Multiplayer Gameplay Programming

 

달리기 Ability를 생성하기 전에, Tick처럼 동작하며 벽 달리기를 수행할 Ability Task C++ 클래스를 생성한다.

 


Ability Task는 델리게이트를 통해 다룰 수 있다.

  • 벽 달리기를 수행할 벽면이 정해졌을 때 발동할 FOnWallRunWallSideDeterminedDelegate 델리게이트를 정의한다.
    콜백 함수에는 벽면의 방향을 전달한다.
  • 벽 달리기가 끝났을 때 발동할 FOnWallRunWallFinishedDelegate 델리게이트를 정의한다.
    더 이상 벽 달리기를 수행할 수 없을 때이다.

 


필요한 클래스를 전방 선언한다.

 


델리게이트를 선언한다.

 


이 함수는 매우 중요하다.

 

모든 Ability Task는 Task 객체를 생성해 반환하는 static 함수를 제공해야 한다.

 

TraceObjectTypes에 지정된 Trace Channel에 해당하는 물체에서는 벽 달리기를 할 수 있도록 한다.

 


Task 활성화 시 호출되는 Activate(), 소멸 시 호출되는 OnDestroy(), Tick처럼 동작하는 TickTask() 함수를 오버라이드한다.

 

 

매 Tick마다 Trace Channel 목록에 해당하는 벽인지 검사해, 달릴 수 있는 벽인지 확인하는 FindRunnableWall() 함수를 선언한다.

감지된 결과가 왼쪽 벽인지 반환하는 IsWallOnTheLeft() 함수를 선언한다.

 

 

필요한 변수와 캐싱할 변수를 선언한다.

  • WallRun_TraceObjectTypes는 CreateWallRunTask() 함수에서 전달받아 설정할 예정이다.


함수들을 구현하기 전에 헤더를 추가한다.

 


Ability Task 활성화 시 호출되는 Activate() 함수를 구현한다.

 

벽에 수행했던 Line Trace 결과를 저장해 사용한다.


UAbilityTask::ShouldBroadcastAbilityTaskDelegates() 함수는 브로드캐스팅이 끝나지 않은 델리게이트가 있는지 반환한다.

 

벽 달리기는 기술적으로 벽에 점프한 후 착지해서 달리는 것이기 때문에 Landed() 함수를 실행해준다.

  • Landed() 함수가 내부적으로 공중에서의 동작들을 종료시켜주는 처리를 수행한다.

 

벽 달리기지만, 실제로는 Flying 모드에서 움직이도록 구현한다.

 

 

캐릭터 클래스의 Landed() 함수에서 점프 상태를 나타내는 이펙트를 제거하는 처리도 한다.

  • 그러므로, 자연스럽게 점프 상태에서 벽 달리기 상태로 전환될 수 있다.

 


CreateWallRunTask() 함수를 구현한다.

  • 구현부에는 static을 쓰지 않는다.


Ability Task를 생성할 때는 NewObject() 함수를 사용하지 않고, NewAbilityTask() 함수로 생성한다.

  • 매 Tick마다 TickTask() 함수를 통해 달릴 수 있는 벽인지 확인할 것이므로, bTickingTask = true로 설정해준다.
  • 같은 클래스 내부의 함수이므로, 바로 protected 변수에 접근할 수 있다.

 


TickTask() 함수를 구현한다.

  • WallRunDirection은 왼쪽, 오른쪽 벽에서 앞으로 달릴 방향이다.
  • 달리는 도중에 서서히 떨어지게 하기 위해서는, 실제로는 GetGravityZ()에 좀 더 큰 값을 곱해야 한다.
    여기서는 거의 떨어지지 않게 의도하기 때문에 0에 가까운 값으로 설정했다.
  • SetPlaneConstraint() 함수를 사용하면, 캐릭터의 이동을 특정한 평면으로 제한할 수 있다.

 


달릴 수 있는 벽인지 확인하는 FindRunnableWall() 함수를 구현한다.

  • 첫 번째 Line Trace는 앞에 장애물이 없는지 검사한다.
  • 두 번째는 내적을 활용해 액터의 좌/우 벡터와 벽면의 법선 벡터가 27° 미만으로 차이나는지 검사한다.

 


벽이 왼쪽에 있는지 반환하는 IsWallOnTheLeft() 함수도 내적을 활용해 구현한다.

 

 

Ability Task가 소멸할 때 호출되는 OnDestroy() 구현한다.

  • 종료 혹은 정리 함수의 Super Call은 로직의 마지막에 위치하도록 해야 한다.
  • 이동 모드를 Falling으로 설정하고 이동 제한을 해제한다.

 

 

벽 달리기 능력인 GA_WallRun C++ 클래스를 생성한다.

 

 

방금 작성했던 Ability Task를 사용할 것이므로 전방 선언해준다.

 


생성자를 선언하고 구현한다.

  • InstancedPerActor로 설정되면 액터에 GiveAbility() 함수를 통해 한 번 능력이 부여되고, 이후에는 ActivateAbility(), EndAbility() 함수를 통해 여러 번 능력이 실행될 수 있다.

 


OnGiveAbility(), OnRemoveAbility(), CanActivateAbility(), ActivateAbility(), EndAbility() 함수를 오버라이드한다.

  • OnGiveAbility() 함수는 GiveAbility() 함수를 통해 능력이 부여될 때 호출된다.
  • OnRemoveAbility() 함수는 능력이 다시 회수될 때 호출된다.

 


Capsule 컴포넌트의 OnComponentHit 델리게이트에 등록한 OnCapsuleComponentHit() 콜백 함수를 선언한다.

  • 이때 ActivateAbility() 함수를 통해 능력을 활성화하고 Ability Task를 실행해 실질적으로 벽 달리기를 수행한다.

 

Ability Task의 OnWallSideDetermined 델리게이트에 등록할 같은 이름의 콜백 함수도 선언한다.

 


아까 작성했던 벽 달리기 Ability Task를 수행할 객체를 담을 변수와 벽으로 인식할 Trace Channel, 벽 달리기 도중 적용할 이펙트를 선언한다.

  • GAS에서는 태그를 통해 어떤 상태인지 확인한다.
  • 상태 태그를 통해 왼쪽 벽인지 오른쪽 벽인지 나타내기 위한 이펙트이다.
  • 애니메이션에서도 이 태그를 통해 왼쪽으로 재생할지 오른쪽으로 재생할지 결정한다.

 


함수들을 구현하기 전에 헤더를 추가한다.

 


액터에 능력 부여 시 호출되는 OnGiveAbility() 함수를 구현한다.

  • 캐릭터의 Capsule 컴포넌트가 벽에 부딪힐 때, 벽 달리기를 시작하는 콜백 함수를 실행하도록 한다.

 


능력이 다시 회수될 때 호출되는 OnRemoveAbility() 함수를 구현한다.

 


CanActivateAbility() 함수를 통해 공중에 떠 있을 때만 벽 달리기를 할 수 있도록 한다.

 


ActivateAbility() 함수에서는 벽 달리기 Ability Task의 static 함수를 통해 객체를 생성해 사용한다.

 

델리게이트에 콜백 함수를 등록하고, ReadyForActivation() 함수를 꼭 호출해주어야 한다.

 

 

OnCapsuleComponentHit() 함수를 구현한다.

  • 능력 자체에서 액터의 Ability System 컴포넌트를 가져와 자기 자신을 실행하도록 할 수도 있다.

 


OnWallSideDetermined() 함수를 구현한다.

  • Ability Task의 델리게이트를 통해 이벤트가 발생하고 이 함수에서 왼쪽, 오른쪽에 따라 이펙트를 통해 상태 태그를 적용한다.

 


EndAbility() 함수에서는 Ability Task를 정리하고 이펙트를 제거한다.

 


왼쪽 벽 달리기 상태를 나타내기 위해 적용할 GE_WallRunLeft 이펙트를 생성한다.

  • Duration Policy: Infinite로 설정한다.
  • 이펙트의 태그인 GameplayEffectAssetTag와 액터에 적용될 GrantedTags에 State.Movement.WallRun.Left 태그를 설정한다.

 

 

오른쪽 벽 달리기 상태를 나타내기 위해 적용할 GE_WallRunRight 이펙트도 GE_WallRunLeft를 복제해 생성한다.

  • Duration Policy: Infinite로 설정한다.
  • 이펙트의 태그인 GameplayEffectAssetTag와 액터에 적용될 GrantedTags에 State.Movement.WallRun.Right 태그를 설정한다.

 

 

달리기 능력 BP인 BP_GA_WallRun를 생성한다.

 

좌우측에 따라 적용할 이펙트와 벽으로 인식할 Trace Channel을 설정한다.

 

능력의 고유 태그인 Ability Tags에 Ability.Movement.WallRun 태그를 설정한다.

 

Activation Owned Tags에 State.Movement.WallRun 태그를 설정한다.

  • Instancing Policy가 InstancedPerActor이므로, 이펙트를 사용하지 않고 능력 실행 중에 State.Movement.WallRun 태그를 적용할 수 있다.

 


캐릭터의 기본 이펙트와 능력을 적용하는 데 사용되는 BaseCharacter 데이터 에셋에 BP_GA_WallRun 벽 달리기 능력을 추가한다.

 


애니메이션 BP에 벽 달리기 중인지 나타내는 IsWallRunning 변수와 좌/우측에 따라 애니메이션을 미러해 재생할지 나타내는 MirrorWallRun? 변수를 추가한다.

 

 

이벤트 그래프에서 변수를 갱신하는 부분을 추가한다.

 

Has Matching Gameplay Tag 노드를 통해 액터의 Ability System 컴포넌트가 해당 태그를 갖고 있는지 확인할 수 있다.

 

 

애니메이션 미러링은 애니메이션을 거울에 비춘 것처럼 대칭시켜 재생할 수 있도록 해주는 기능이다.

 

 

애니메이션 미러링

미러 데이터 테이블을 사용하여 언리얼 엔진에서 애니메이션을 미러링합니다.

docs.unrealengine.com


애님 그래프를 수정한다.

 


Anim Preview Editor에서 테스트 해본다.

 

 

잘 되나, 벽을 만나기 전까지는 도중에 끊을 수 없는 문제가 있다.

 


점프 능력인 GA_Jump에 벽 달리기 도중 점프를 할 수 있도록 수정해본다.

  • 이 구현은 캐릭터 클래스 등 다른 곳에 구현해도 된다.

 

달리기 능력을 종료시키기 위한 태그와 벽에서 점프할 때 적용할 힘의 양을 선언한다.

 


기능을 추가하기 전에 헤더를 추가한다.

 


CanActivateAbility() 함수를 수정해 벽 달리기 중에도 뛸 수 있도록 수정한다.

  • 사실 CanActivateAbility() 함수에는 조건을 더 추가하지 않아도 되긴 하다.


Character 포인터의 const 키워드는 제거한다.


UNavMoveComponent::IsJumpAllowed() 함수로 점프가 가능한지 확인할 수 있다.

  • 벽 달리기를 시작할 때 ACharacter::Landed() 함수를 실행했으므로, 다시 점프할 수 있는 상태이다.

 

UAbilitySystemComponent::HasMatchingGameplayTag() 함수로 Ability System 컴포넌트가 해당 태그를 갖고 있는지 확인할 수 있다.

 


ActivateAbility() 함수를 수정해 벽 달리기 도중에 점프하는 기능을 추가한다.

  • 그냥 점프가 아니라, 키 입력을 누르고 있는 방향으로 점프하길 원한다.

 

Acceleration은 이동하려는 의지의 방향이다.

  • 쉽게 말해 입력의 방향이다.
  • 앞으로 가다가 우측 버튼을 누르면 가속은 오른쪽 방향을 가리킨다.

 

벽 달리기 도중에 점프하면 WallRunStateTag와 일치하는 벽 달리기 능력을 종료하고, ACharacter::LaunchCharacter() 함수로 캐릭터를 쏘아 올려 점프와 비슷한 효과를 준다.

 


BP_GA_WallRun의 Ability Tags에 State.Movement.WallRun을 추가한다.

  • 상태 태그이긴 하지만, CancelAbilities() 함수가 Ability Tags를 확인해 수행되기 때문이다.

 


BP_GA_Jump의 ActivateAbility() 함수에 있는 CancelAbilities() 함수에 전달할 WallRunStateTag 태그를 설정해준다.

 

 

달리다가 도중에 점프를 통해 끊는 기능을 추가했고 멀티 플레이어에서도 잘 된다.

 

'Unreal Engine > Advanced UE5 Multiplayer Programming' 카테고리의 다른 글

인벤토리 구조  (0) 2023.05.16
능력 간의 관계 설정  (0) 2023.05.15
뛰어넘기 능력  (0) 2023.05.13
달리기 능력  (0) 2023.05.12
앉기 능력  (0) 2023.05.11
profile

Make Unreal REAL.

@diesuki4

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

검색 태그