오늘은 아케인보드 시스템에서 캐릭터 클래스 변경 시 이전 클래스의 룬 데이터가 새로운 클래스에 잘못 표시되는 버그를 해결했음
확인해보니 메모리 상 데이터 정리가 불완전해서 발생한 문제였음. 에디터에서는 정상 작동하지만 패키징 빌드에서만 나타나는 까다로운 버그였음

증상:
핵심 추적 포인트:
클래스 변경 과정에서의 데이터 상태
세이브/로드 시점의 실제 데이터!
UI 업데이트 순서와 타이밍
추가한 디버깅 로그:
// SetCurrClass 함수
UE_LOG(LogTemp, Warning, TEXT("클래스 변경 전 배치된 룬 개수: %d"), PlacedRunes.Num());
for (int32 i = 0; i < PlacedRunes.Num(); i++) {
UE_LOG(LogTemp, Warning, TEXT(" 룬 %d: ID=%d, Pos=(%d,%d)"),
i, PlacedRunes[i].RuneID, PlacedRunes[i].Pos.X, PlacedRunes[i].Pos.Y);
}
// LoadSavedData 함수
UE_LOG(LogTemp, Warning, TEXT("로드할 룬 개수: %d"), Runes.Num());
UE_LOG(LogTemp, Warning, TEXT("최종 PlacedRunes 개수: %d"), PlacedRunes.Num());
로그 패턴 분석:
[찬 → 메르시 클래스 변경]
LogTemp: Warning: 클래스 변경 전 배치된 룬 개수: 1
LogTemp: Warning: 룬 0: ID=2, Pos=(0,0)
LogTemp: Warning: 그리드 상태 초기화 시작
LogTemp: Warning: 초기화 후 배치된 룬 개수: 1 // ← 문제 발견!
LogTemp: Warning: 초기화 후 룬 0: ID=2, Pos=(0,0)
핵심 발견:
InitGridState() 호출 후에도 PlacedRunes가 그대로 남아있음문제가 된 코드 흐름:
void UGS_ArcaneBoardManager::InitGridState(){
CurrGridState.Empty();
// PlacedRunes 초기화 안함
if (IsValid(CurrGridLayout))
{
for (const FGridCellData& Cell : CurrGridLayout->GridCells)
{
FGridCellData NewCell = Cell;
if (NewCell.State == EGridCellState::Empty)
{
NewCell.PlacedRuneID = 0;
}
else if (NewCell.State == EGridCellState::Occupied)
{
PlacedRunes.Add(FPlacedRuneInfo(Cell.PlacedRuneID, Cell.Pos));
}
CurrGridState.Add(Cell.Pos, NewCell);
if (Cell.bIsSpecialCell)
{
SpecialCellPos = Cell.Pos;
}
}
}
}
bool UGS_ArcaneBoardManager::SetCurrClass(ECharacterClass NewClass) {
// ...
if (bNeedGridReset) {
InitGridState(); // 그리드 상태만 초기화
CalculateStatEffects(); // 뒤섞인 PlacedRunes로 계산!
AppliedBoardStats = CurrBoardStats;
}
// ...
}
InitGridState() 함수의 역할:
PlacedRunes 배열은 초기화 하지 않음결과:
초기화: InitGridState()에서 정리
void UGS_ArcaneBoardManager::InitGridState() {
PlacedRunes.Empty(); // 추가된 한 줄
CurrGridState.Empty();
// 나머지 초기화 로직...
}
에디터에서 정상인 이유:
패키징에서 문제 드러난 이유:
해결된 문제:
얻은 교훈: