본문 바로가기

Memorize: RECALL

Buff Storage 클래스를 설계한 이유

개요

스턴, 독 등의 부모 클래스인 Buff 클래스를 설계하는데, 고민해 볼 문제가 발생했다.

각 버프마다 각 캐릭터에 저장해야 할 정보가 있다. 대표적인 예시는 최대 5 스택까지 중첩되는 독이 있다.

그런데 이를 저장할 방법이 없던 것이었다.

 

어떻게 해야 독 스택을 저장할 수 있을까?

접근 방법

우선 각 캐릭터마다 저장되는 버프에 '독립적인' 정보라는 점에서 static 변수를 먼저 생각하게 되었다.

그러나 static 변수는 캐릭터마다 독립적이지 못하기에 사용할 수 없다.

하지만 독립적인 변수라는 접근은 유지할 가치가 있었다.

 

그다음에는 '각 캐릭터마다 저장된다'는 점에 주목했다. 각 캐릭터마다 저장된다는 조건을 충족하는 가장 간단한 방법은 캐릭터의 멤버 변수였다. 그렇다면 '각 버프 클래스 별로 정보를 저장해야 한다.'라는 조건은 어떻게 충족해야 할까?

각 버프 클래스마다 다르다는 점에서 버프 클래스(TSubclassOf<ABuff>)를 키 값으로 하는 Map을 떠올리게 되었다.

 

이제 '개별 캐릭터'와 '개별 버프 클래스'라는 조건을 충족했으므로, 남은 조건은 '다른 정보'이다. Map의 Value로 사용하기 위해서는 같은 타입을 가지면서, 다른 정보를 가져야 한다. 자연스럽게 다형성을 이용하는 방법이 생각났다.

비어있는 클래스를 제작한 후, 각 버프마다 필요한 정보를 담는 버프 스토리지 클래스를 제작한다.

 

캐릭터 클래스에 있는 BuffStorages 변수

 

이제는 모든 버프 클래스를 순회하며 해당 버프에 해당하는 버프 스토리지를 저장에서 맵에 추가하면 해결이다.

다행히 UE4는 TObjectIterator<UClass>를 통해 모든 클래스를 순회할 수 있다. 모든 클래스를 순회하며 버프 클래스를 상속하는지 확인한 후에, 상속한다면 그 버프에 해당하는 버프 스토리지를 제작한다.

 

BeginPlay에서 모든 클래스를 돌며 Buff를 상속받는지 확인한다.

 

개별 버프 클래스마다 필요한 버프 스토리지는 버프 클래스에 가상 함수를 두어 버프 클래스에서 제작하도록 책임을 두어 해결할 수 있었다.

 

자신의 클래스에 해당하는 BuffStorage를 생성하는 책임은 각 클래스에 넘긴다.

 

결론

사실 아직도 버프 클래스의 설계를 바꿔서 더 깔끔하게 할 수 있지 않았을까 고민한다. 그러나 아직은 지금의 설계가 가장 깔끔하고, 접근하기 용이하다고 생각한다. 만약 나중에 더 나은 설계를 발견해서 변경하게 된다면 다시 포스팅할 것이다.

 

버프 스토리지를 통해 캐릭터마다의 스턴 카운트를 저장할 수 있었다.