8주차 과제로 기존의 코인, 지뢰, 회복 아이템 외에 추가로 아이템 클래스를 구현하는 과제가 있어, 먹으면 느려지는 아이템을 구현해봤다
기존의 회복 아이템과 코드가 유사
하지만 아이템의 지속시간이 끝나고 캐릭터의 이동속도를 다시 올리는 부분을 Lambda 함수를 사용하는 타이머로 지정해서 구현했는데 생각한대로 되지 않았다
TimerHandle에 대한 고민을 좀 했는데
각 아이템마다 TimerHandle을 쓰면 각 아이템의 지속시간을 추적할 수 있고 중첩도 가능하지만, 아이템이 Destroy()되고 나면 이 TimerHandle을 관리할 수 없다는 문제가 있고
그렇다고 GameState나 Character에서 하나의 TimerHandle을 사용하면 TimerHandle을 간단하게 관리하지만, 각 아이템의 지속시간을 추적할 수 없고 중첩이 되어도 지속시간이 지나고 중첩 횟수가 줄어야하는데 줄지가 않는 문제가 있었다
둘 중 어떻게 하더라도 직접 TimerHandle을 만들어 줘야하는 건 똑같으니까, (중첩에 문제가 없는 위 코드와 같이) 각 아이템마다 TimerHandle을 만든 코드에서 어떻게 하면 TimerHandle을 기억할 수 있을까에 대해 생각하다가
GameState에서 TArray나 TMap에 여러 개의 TimerHandle을 가지고 있으면 되겠다고 생각을 했는데, 그럼 여기서 "여러 개의 TimerHandle"을 어떻게 만들것인가에 대한 늪에 빠졌다.
기본적으로 C++에서는 저런 컨테이너에 넣을려면 객체가 있어야 그 객체를 insert() 하거나 Push_back()을 해서 컨테이너에 저장을 할 수 있었다
근데 언리얼의 TMap은 그냥 Key를 추가하면 Value에 해당하는 객체도 알아서 생성되어 컨테이너에 저장할 수 있었다 (C++에서도 이렇게 되는게 있긴 함)
TMap<FName, FTimerHandle> SlowTimerHandles
에 TimerHandle을 하나 생성하고, 생성한 TimerHandle을 참조하는 방식으로 사용이렇게 하고나면 아이템 중첩에도 문제가 없고 TimerHandle 관리까지 할 수가 있었다. 하지만 지속시간이 끝난 아이템에 대한 TimerHandle을 처리할 필요가 있었다
SlowTimerHandles
의 크기도 적절하게 유지가 되면서 메모리 낭비를 하지 않음이걸로도 언제 어디서 TimerHandle을 삭제해야할까에 대해 고민을 좀 오래하다가 ChatGPT에 물어보니 그냥 Lambda에서 처리하면 된다고해서 이런 고민을 한 것에 대해 약간 짜증이 났다.
그래도 ChatGPT의 도움을 받아 내가 원하는 방식으로 동작하도록 코드를 만들 수 있었다
추가로 C++에서도 언리얼의 TMap처럼 동작하는 게 있다고 했는데, map의 operator[]
이다
class A
{
public:
int add(int x, int y) { return x + y; }
public:
int a = 10;
};
참조 사이트
1. https://wecandev.tistory.com/62
2. https://dev.epicgames.com/documentation/en-us/unreal-engine/map-containers-in-unreal-engine
3. https://cplusplus.com/reference/map/map/operator[]/