티스토리 뷰

Spawning Projectiles

현재 AuraProjectileSpell은 단순히 문자열만 출력할 뿐, 실질적인 기능은 없는 상태이다.

따라서 실제 Projectile을 생성하여 캐릭터의 무기 끝부분에서 Spawn되도록 기능을 구현할 것이다.

이에 가장먼저 AuraProjectileSpell에 Projectile로 사용할 클래스 변수를 추가해주자.

 

Projectile은 로컬 클라이언트에서 직접 Spawn하지 않고, 서버에서 Spawn하게 된다.

따라서 AuraProjectile에서 Replication을 활성화해 주자.

 

다시 AuraProjectileSpell로 돌아와서, Projectile은 서버에서만 Spawn해야 하므로 현재 어빌리티가 서버 권환을 가지고 있는 지 확인해야 한다.

GAS의 Gameplay Ability에는 권한을 확인할 수 있는 기능이 존재하며, 권한 여부를 bool 값으로 반환받을 수 있다.

우리는 HasAuthority라는 권한 확인 함수를 사용할 것이며, 여기에는 Activation Info 포인터가 필요하다.

Gameplay Ability에는 ActivationInfo가 존재하기 때문에, 해당 값을 주소로 전달한다.

 

이제 Projectile Spawn 방식을 결정할 차례이다.

일반적ㅇs Actor Spawn은 GetWorld()를 통해 가능하며, 생성할 Actor 클래스와 Spawn 위치 및 회전 값 등을 전달할 수 있다.

하지만 이번 Projectile의 경우 공중 이동, 대상과 충돌, Gameplay Effect 적용 Damage 관련 정보 보유 등의 기능을 가지게 될 예정이므로, Actor가 완전히 Spawn되기 전에 Projectile 내부의 여러 속성을 먼저 설정할 필요가 있다.

 

여기서 사용하는 것이 SpawnActorDeferred 함수다.

해당 함수는 Actor Spawn을 지연시켜, Spawn이 완료되기 전에 속성을 설정할 수 있다.

매개변수로는 다음과 같은 값들이 필요하다.

Projectile Class
어떤 Projectile 클래스를 생성할 것인지 전달

Spawn Transform
Projectile을 어떤 Transform으로 생성할 것인지 전달
현재 시점에는 위치 및 회전 값이 설정되지 않은 상태

Projectile Owner
Projectile의 Owner (현재 Gameplay Ability의 Owner)

Projectile Instigator
Instigator는 현재 Projectile 생성 행동을 일으킨 Pawn을 의미
이번 상황에서는 Projectile을 발사하는 캐릭터
Owner Actor를 가져와 Pawn으로 캐스팅

Collision Handling Method
Projectile Spawn 시 Collision 상황과 관계 없이 항상 Spawn되도록 설정 (AlwaysSpawn)

 

현재 SpawnTransform 변수 자체는 만들었지만, 실제 값은 정의되지 않은 상태이다.

따라서 위치와 회전 값이 모두 미설정되어있으며, 어디에서 Spawn할 것인지 결정해야 한다.

가장 간단하게 구현한다면 Ability를 소유한 Actor의 위치를 생각할 수 있으나, 우리가 원하는 것은 캐릭터가 들고 있는 Staff의 끝 부분에 Spawn되기를 원한다.

 

하지만 우리는 이 Ability가 AuraCharacter와 같이 특정 클래스에 직접 의존하지 않기를 원한다.

즉, AuraCharacter로 직접 Cast하여 Weapon에 직접 접근하는 방식은 피할 것이다.

대신 해당 Ability를 사용하는 Actor가 가지고 있는 Weapon의 Socket 위치를 가져오는 공통된 방식을 사용할 것이며, 이를 위해 Interface를 사용한다.

 

프로젝트에는 이미 CombatInterface가 존재하며, 해당 Interface는 Aura Character와 Aura Enemy가 공유하는 전투 관련 기능을 정의하는 용도이다.

따라서 CombatInterface에 공통적으로 Socket 위치를 가져올 수 있는 함수를 추가해 줄 것이다.

기본 정의에서는 빈 FVector만 반환하며, Combat Interface를 구현하는 클래스에서 해당 함수를 Override하여 각자의 Socket 위치를 반환하는 형태로 사용하게 된다.

 

AuraCharacterBase 클래스에는 Weapon이 존재하기에, Weapon에는 Projectile이 생성될 위치를 나타내는 Socket이 필요하다.

우선 Weapon에는 여러 종류의 Socket이 존재할 수 있기 때문에 Projectile 발사에 사용할 Sokcet 이름을 별도로 저장하고, Interface에서 생성한 함수를 Override한다.

 

상속받은 함수에서는 방금 생성한 SocketName을 통해 Socket 위치를 반환하게 된다.

 

다시 AuraProjectileSpell로 돌아와서, 여기서 Combat Interface를 활용한다.

Ability를 사용하는 주체인 Avatar Actor를 가져와서 CombatInterface로 캐스팅하여 접근한다.

여기서 Owner Actor를 사용하지 않는 이유에 대해서 잠시 헷갈렸는데, Owner Actor는 ASC를 소유하고 있는 Actor로 여기서는 PlayerState에 해당한다.

Abatar Actor는 그 ASC를 이용해서 실제 게임에서 행동하는 Actor이기에 Character에 해당하기에 Avatar Actor를 사용한다.

 

마찬가지로 Interface를 통해 소켓 위치에 접근하여 위치 정보를 얻어주며, SpawnTransform 변수에 해당 위치 값을 할당한다.

 

현재 사용중인 SpawnActorDeferred 함수는 AuraProjectile 타입의 포인터를 반환한다.

따라서 해당 반환값을 로컬 변수로 저장해주자.

현상태에서는 SpawnActorDeferred를 호출하여 Projectile 생성을 시작했지만 SPawn 과정은 아직 완료되지 않은 상태이다.

 

Spawn 완료를 위해서는 Projectile 변수를 통해 FinishSpawning 함수를 호출해 SpawnTransform을 전달해주어야 한다.

이를 통해 Projectile의 Spawn이 최종적으로 완료된다.

 

컴파일을 하고 가장먼저 AuraCharacter에 Socket 이름을 작성해주자.

Weapn에는 현재 아래쪽의 Tail Socket와 상단 끝부분의 Tip Socket이 존재하며, 우리가 사용할 Spawn 위치는 Tip Socket이다.

 

그리고 Projectile을 발사하는 Gameplay Ability인 FireBolt에서 Projectile Class를 BP_FireBolt로 설정해주자.

 

이제 적을 클릭하면 성공적으로 GameAbility가 작동하는 모습을 볼 수 있다.

 

하지만 현재 Rotation 값은 설정을 안했기에, 캐릭터 위치가 어디던 간에 매번 동일한 방향으로 이동한다.

따라서 목표를 조준하고 방향을 계산한 후 해당 방향으로 Projectile을 발사할 수 있도록 Roation 설정이 필요하다.

그리고 FireBolt에 맞는 애니메이션도 따로 할당하여 구현해줄 것이다.

 

현재보다 복잡한 Ability를 구현하려면 GAS에 대해 더 학습해야 하며, 특히 Gameplay Ability에서 할 수 있는 작업과 Ability Task에 대해 학습할 필요가 있다.

따라서 앞으로 이어지는 강의에서 Ability Task를 자세히 학습할 예정이다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/07   »
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
글 보관함