게임 개발/Tower of Rings

6/30 - 링 ID 16번 // 7/1 - 공격 파티클 개편, 링 ID 20, 21번

CastleMouse 2022. 7. 2. 01:32

오늘의 결과

어제는 16(귀환)번 하나밖에 안만들어서 기록을 건너뛰었다. 그리고 오늘 만든 링은 20(절단), 21(저주)링이다. 각각 짤의 두/세번째 링이다. 오늘은 아주 중요한 변경점이 있었다. 첫번째는 기존의 공격 파티클을 관리하는 방식을 바꾼 것,  두번째는 링을 덱에서 제거 시 앞으로 사용되지 않을 오브젝트 풀에 있는 오브젝트들을 삭제하도록 한 것이다.

 

0) 어제만든 16번 링은 짤에 담겨있진 않지만 일정 확률로 몬스터를 시작 위치로 되돌린다. 이는 movedDistance를 0으로 만들어주면 PathCreator가 Path의 시작점으로 위치를 대응시켜주기 때문에 간단하게 구현할 수 있었다.

 

1) 20번 링은 랜덤한 대상을 공격하며 적 "현재" HP 비례 데미지를 입힌다. 그래서 타격한 몬스터의 curHP와 링의 curATK를 이용하여 데미지를 계산했다.

 

2) 21번 링은 가장 HP가 높은 대상을 공격하며, 공격 시 몬스터에 저주 스택을 쌓는다. 저주 스택이 있는 몬스터는 형태가 변하며(짤에서는 임시로 회색으로 변하도록 했음) 사망시 모든 적에게 자신의 최대 HP * 쌓인 스택 %만큼 데미지를 입힌다. 다만 이 링을 직접 배치해보니 너무 밸런스 붕괴인것 같아서 수치를 좀 줄일 계획이다. 이 링은 맹독링이 몬스터에게 poisonStack을 쌓는것과 비슷하게 curseStack을 공격할 때마다 쌓도록 했다. 그리고 몬스터를 게임에서 제거하는 RemoveFromScene()함수는 오브젝트 풀에 몬스터를 되돌려주는(그리고 되돌리기 전에 우선 변수들의 변화를 처리함) InvokeReturnMonsterToPool()함수를 부르는데, 여기에서는 만약 curseStack이 하나라도 쌓여있다면 AE_CurseDead()함수를 불러 모든 살아있는 몬스터에 자신의 baseHP와 curStack을 이용하며 데미지를 주도록 했다.

 

3) 오늘의 가장 큰 변경점은 Particle Checker이다. 모든 공격 파티클들은 Particle Checker 라는 component를 가지도록 했다. 이 Particle Checker는 Awake에서 게임오브젝트에 붙어있는 particle system과 모든 자식 particle system들을 불러오고, 이름을 파싱하여 자신이 어느 링의 공격효과에 해당하는 파티클인지 확인하여 변수 id에 그 값을 저장한다. GameManager.instance.GetParticleFromPool()을 하면 이제 더이상 Particle System이 아닌 이 새로운 component를 받아오게 되는데, 받아온 Paricle Checker의 PlayParticle(부모 transform, 지속시간)함수를 실행하면 게임오브젝트를 부모 오브젝트의 childrend으로 넣으면서 지속시간동안 플레이한다(지속시간은 0.0f로 하면 기본 지속시간이 적용된다).

 

4) Particle Checker의 가장 큰 장점은

    a. 이제 더이상 파티클을 활성화 및 오브젝트 풀에 되돌리는 것에 신경쓸 필요가 없다. PlayParticle()함수를 실행하면 자동으로 오브젝트가 SetActive(true)되며, OnEnable()과 OnDisable()에서 알아서 paritlce.Play()와 GameManager.instance.ReturnParticleToPool()를 해주기 때문이다.

    b. Monster는 더이상 ParticleSystem[] particles와 int[] particlesID 배열을 가질 필요가 없고, 자신이 플레이했던 파티클을 모두 체크하여 오브젝트 풀에 되돌려줄 필요가 없다. 이제 각 파티클들이 독립적으로 자신이 종료되었는지 확인하고 오브젝트 풀에 되돌리기 때문이다.

 

5) 종합하면 기존의 파티클을 플레이 하는 과정은

    a. 오브젝트 풀에서 파티클을 받아오기->Monster의 particles와 particlesID배열에 받아온 파티클&id 저장하기->피격 파티클을 재생했던 몬스터가 파티클의 재생이 끝났는지 Invoke로 일정시간마다 감시하기->죽은 파티클이 있다면 오브젝트 풀에 되돌리기->만일 몬스터 사망/게임 종료이면 모든 파티클들 오브젝트 풀에 되돌리기

였으나...

    b. 오브젝트 풀에서 파티클을 받아오기->받아온 파티클의 PlayParticle(Monster, duration) 멤버함수 실행하기->만일 몬스터 사망/게임 종료이면 StopParticle() 멤버함수 실행하기

로 매우 간소화되었다.

 

6) 마지막으로 링을 덱에서 제거하는 경우, GameManager.EmptyParticlePool(ringID)과 GameManager.EmptyBulletPool(ringID)함수를 작성하여 더이상 사용하지 않을 공격 파티클/Bullet을 제거하도록 하였다. 실제로 게임을 하면 여러 종류의 링이 덱에 추가되었다가 삭제되곤 할텐데, 더이상 사용할 일이 없는(즉, 덱에서 제거된) 파티클과 Bullet들이 Hierachy에 남아있으면 낭비라는 생각이 들어서 RemoveRingFromDeck()함수에서 새로 작성한 두 함수를 부르도록 했다. 짤 우측 컴포넌트 창에서 Debug Flag를 누르면 좌측의 Hierachy 스크롤이 짧아지는 것을 볼수있다. 사실 실제로는 훨씬 더 많이 사라지는 중이다. 파티클들은 몬스터들의 자식 오브젝트로 저장되어 있는 상태이기 때문. 즉, 스크롤이 짧아진 건 Bullet이 제거됨으로 인한 변화만 보여서 그런거다. Monster라 쓰여있는 오브젝트들을 모두 눌러보면 변화를 확인할 수 있는데 짤에는 담는 것을 깜빡했다. 암튼 잘 제거 되는건 맞아!

 

 

내일 할일은... 사실 오늘 코드 짜면서 (이거 볼 사람이 있을진 모르겠지만) 남이 함수의 용도를 알기 좀 어려울것 같다는 생각이 들어서, 내일은 전체적으로 코드를 정리하고 주석을 달 것이다.

- 코드 정리 및 주석 달기

'게임 개발 > Tower of Rings' 카테고리의 다른 글

7/7 - 링 ID 25~27번  (0) 2022.07.08
7/3 - 링 ID 22~24번  (0) 2022.07.04
6/29 - 링 ID 12~15번  (0) 2022.06.30
6/28 - 링 ID 11, 18번  (0) 2022.06.29
6/25 - 링 ID 7, 8, 19번  (0) 2022.06.25