개발/유니티

[충동 멈춰 어플]스텟을, 메인화면에서 없애고, 다른 버튼으로

kimchangmin02 2025. 9. 12. 22:34

왜 이런 현상이 발생할까요? (원인)

이 문제의 원인은 앵커(Anchor) 때문입니다. 앵커는 UI 요소의 '기준점'으로, "나는 화면의 어디를 기준으로 내 위치를 잡을 것인가?"를 결정합니다.

사용자님의 스탯 UI들은 처음에 Canvas(전체 화면)의 자식으로 만들어졌을 겁니다. 그래서 그 UI들의 앵커는 '화면 전체'의 오른쪽 아래를 기준으로 설정되어 있습니다.

그런데 이 UI들을 MyInfoPanel로 옮기더라도, 이 '옛날 집 주소(화면 전체 기준)'를 기억하고 있는 앵커 설정은 자동으로 바뀌지 않습니다. 그래서 자식들은 새로운 부모인 MyInfoPanel을 무시하고 여전히 화면 전체의 오른쪽 아래에 있으려고 하는 것입니다.


해결 방법

자식들의 '기준점(앵커)'을 새로운 부모인 MyInfoPanel로 다시 설정해주면 모든 문제가 해결됩니다.

방법 1: 앵커 프리셋으로 한 번에 재설정하기 (가장 빠르고 추천하는 방법)

이 방법은 자식들의 위치와 기준점을 부모에 맞게 한 번에 '착'하고 붙여주는 마법 같은 기능입니다.

  1. 자식 오브젝트들 선택: Hierarchy 창에서 MyInfoPanel 안에 있는 모든 스탯 UI 오브젝트들(텍스트 5개, 버튼 5개 등)을 Shift 키를 누른 채 클릭하여 전부 선택합니다.
  2. 앵커 프리셋 창 열기: Inspector 창 맨 위에 있는 Rect Transform 컴포넌트를 봅니다. 왼쪽 위에 사각형 모양의 아이콘이 있는데, 이것이 **앵커 프리셋(Anchor Presets)**입니다. 이 아이콘을 클릭하세요.
  3. 위치와 앵커 동시 설정 (핵심!): 다양한 사각형 모양이 격자로 나타납니다.
    • 키보드의 Alt 키와 Shift 키를 동시에 누른 상태로, 원하는 정렬 기준을 클릭합니다. 예를 들어, UI들을 패널의 중앙에 정렬하고 싶다면 middle-center (가운데 점 하나 있는 사각형)를 클릭합니다.
    • Alt 키의 역할: UI의 **'실제 위치'**를 앵커가 있는 곳으로 즉시 이동시킵니다.
    • Shift 키의 역할: UI의 **'피봇(Pivot)'**도 앵커와 함께 이동시킵니다.
  4. 결과: 10개의 UI 오브젝트들이 모두 MyInfoPanel의 중앙으로 순간이동하고, 이제 그들의 위치 기준점(앵커)도 MyInfoPanel의 중앙으로 변경됩니다. 이제 MyInfoPanel을 움직이면 자식들도 모두 따라서 움직입니다.
  5. 세부 위치 조정: 중앙으로 모인 UI들을 이제 마우스로 끌어서 원하는 대로 자유롭게 배치하시면 됩니다. 이제는 패널의 경계를 벗어나지 않을 겁니다.

방법 2: 레이아웃 그룹(Layout Group)으로 반자동 정렬하기

Grid Layout Group이 싫으시다면, 한 방향으로만 정렬을 도와주는 Vertical Layout Group은 아주 좋은 대안이 될 수 있습니다.

  1. MyInfoPanel 안에 빈 게임 오브젝트를 하나 만들고 이름을 StatList 등으로 짓습니다.
  2. StatList 오브젝트에 Vertical Layout Group 컴포넌트를 추가합니다.
    • 이 컴포넌트는 자식들을 위에서 아래로 자동으로 정렬해 줍니다.
    • Spacing 값으로 항목 사이의 간격을 조절하고, Padding으로 안쪽 여백을 설정할 수 있습니다.
  3. 이제 모든 스탯 UI 오브젝트들(텍스트와 버튼)을 StatList의 자식으로 넣습니다. 그러면 위에서 아래로 깔끔하게 정렬됩니다.
  4. StatList 오브젝트 자체는 MyInfoPanel 안에서 자유롭게 위치를 옮길 수 있습니다.

장점:

  • 항목들의 수직 정렬과 간격이 자동으로 관리되어 깔끔합니다.
  • 각 항목의 수평 위치나 크기는 여전히 어느 정도 자유롭게 조절할 수 있습니다. (자식 오브젝트에 Layout Element 컴포넌트를 추가하여 개별 크기 지정 가능)

결론적으로, 지금 상황에서는 1번 방법(앵커 프리셋 변경)이 가장 빠르고 직접적인 해결책입니다. 먼저 이 방법을 시도해보시고, 스탯 UI들을 패널 안에서 원하는 대로 자유롭게 재배치해 보세요.

 

 

 

 

 

 

 

왜 코드를 수정해야 하는가?

사용자님께서 levelText를 포함한 모든 스탯 UI를 MyInfoPanel로 옮기셨습니다. 이 패널은 평소에는 SetActive(false) 상태로 꺼져있습니다.

GameObject가 꺼지면, 그 안에 있는 모든 컴포넌트(Text, Button 등)에 접근할 수 없게 됩니다.

따라서, MyInfoPanel이 꺼져있는 상태에서 GameDataManager가 방송(Invoke)을 하면, UpdateAllUI 함수는 꺼져있는 levelText attackPowerText를 업데이트하려고 시도하다가 NullReferenceException 에러를 발생시킬 겁니다.

 

 

 

해결 방법: 역할을 명확하게 분리하기
하나의 거대한 UpdateAllUI 함수를 두 개의 작고 명확한 함수로 나누는 것이 가장 좋은 해결책입니다.
UpdateMainScreenUI(): 항상 켜져 있는 UI (HP, EXP, 골드)만 책임지는 함수.
UpdateMyInfoPanelUI(): '내 정보' 패널이 켜질 때만 호출되어 그 안의 UI(레벨, 스탯)를 책임지는 함수.

이건 나중에