💻 Magazine 클래스
탄창 객체를 생성하기 위해 CMagazine 클래스를 작성하였다. 탄창은 총알이 다 차있는 Full Mesh와, 총알이 없이 비어있는 Empty Mesh를 각각 생성하고, Empty Mesh위에 Full Mesh를 출력하였다.
재장전 할때는 Full Mesh의 Visibility를 비활성화하여 안보이도록 한 뒤 뒤에 있던 Empty Mesh를 바닥으로 떨어뜨리는 원리로 재장전 모션을 구현하였다.
💻 재장전(Reload) 노티파이
재장전의 Action 타입으로는 다 쓴 탄창을 떼어내는 Eject, 총알이 차있는 새로운 탄창을 가져오는 Spawn, 탄창을 총에 붙이는 Load, 재장전이 끝났음을 알리는 End 까지 총 4가지 단계로 나누었다.
노티파이가 실행될 때 노티파이에 설정한 ActionType 값에 따라 Weapon의 단계별 재장전 함수를 호출해주었다.
💡 SpawnActorDeferred
액터의 생명주기에는 SpawnActor와 SpawnActorDeferred가 각각 존재한다. SpawnActorDeferred는 블루프린트에서는 사용할 수 없고 C++ 클래스에서만 사용 가능하다.
SpawnActorDeferred는 처음에 Spawn이 되고, SpawnInitialize로 초기화하고 난 후, ActorCreated로 생성하면 Spawn 할 액터가 생성은 되었지만 배치되지 않은 상태이다. 배치가 되려면 FinishSpawningActor를 실행시켜야만 배치가 끝나고 Actor의 Spawn이 마침내 완성된다.
즉, SpawnActorDeferred는 처음에 객체를 생성만 시켜놓고, Finish로 완료시키기 전까지는 배치하지 않는다.
이는 객체를 생성하여 배치하기 전에 어떠한 설정을 넣어줘야하는 경우에 유용하게 사용될 수 있다. 어떠한 객체를 생성하고 내가 Begin Play를 실행시켜주고 싶은 경우에 알맞은 함수이다.
1️⃣ Eject Magazine
나는 탄창(Magazine)을 떼어낼 때 탄창의 transform을 총의 탄창 위치(MagazineBone)에 배치시킨 후 Spawn하기 위해 SpawnActorDeferred를 사용하였다.
ACMagazine 클래스로 탄창 객체를 생성하며 매개변수로 탄창클래스, Transform, Owner(null), Instigator(null), AlwaysSpawn을 전달하여 생성을 완료하였고,
해당 객체의 SetEject 함수를 호출해 총알이 차있는 탄창의 Visibility를 비활성화하고, 다 쓴 탄창이 아래로 떨어지도록 Simulate Physics 값을 true로 설정하였다.
이후, 바닥으로 떨어진 탄창이 5초 뒤에 사라지도록 SetLifeSpan 함수를 호출하였고 모든 작업이 끝난 후에서야 FinishSpawning 함수를 호출하여 탄창의 Spawn 과정을 완벽히 끝났다.
이때 FinishSpawing 함수에 전달되는 transform은 확정 Transform이다. SpawnActorDeferred에 전달한 transform은 생성할 때 충돌을 감지하기 위함이고 실제로는 FinishSpawning 에서 배치가 된다.
2️⃣ Spawn Magazine
탄창의 Spawn 단계에서는 새롭게 갈아낄 탄창을 손에 SpawnActor 시켜주는 단계이다. AttachTo 함수는 AttachToComponent 함수를 사용하기 간단하도록 만들어놓은 함수이다.
왼손으로 탄창을 들고있을 위치에 소켓을 생성해주었다.
3️⃣ Load Magazine / 4️⃣ End Reload
Load 단계에서는 UnHideBoneByName 함수를 이용하여 기존 총에 달려있는 탄창의 비활성화를 풀고 활성화시킨다.
이후, 총알 개수(CurrMagazineCount)를 Max 개수만큼 초기화시켜 총알 개수를 채우고, 재장전하며 손에 들고있던 탄창은 Destroy 시켜 없애주었다.
End Reload에서는 재장전 액션이 모두 끝났으므로 bReload 변수를 false로 초기화해주었다.
결과적으로 재장전 모션과 총알 개수의 초기화가 성공적으로 이루어졌다.
위 사진은 다 쓴 탄창이 아래로 떨어져 버려지고, 새롭게 갈아낄 탄창을 왼손에 들고, 총에있는 탄창은 비활성화되어 보이지 않도록 설정한 모습이다.
참조
액터의 수명 주기
액터가 로드 또는 스폰된 후 결국 죽을 때 벌어지는 일에 대해서입니다.
docs.unrealengine.com