개발/하스스톤+전장

하스+전장) #1 (초기 ui구성)

kimchangmin02 2025. 12. 29. 18:13

 

오 ㅋ

 

 

 


 

🃏 목차

1단계: 프로젝트 환경 설정 및 깃(Git) 연동

  • 1.1 유니티 프로젝트 초기화: 2D Core 템플릿 설정 및 16:9 해상도 고정
  • 1.2 캔버스(Canvas) 최적화: Canvas Scaler 설정 (1920x1080 기준, Match 0.5)
  • 1.3 협업 및 버전 관리: .gitignore 설정 및 VS Code를 활용한 GitHub 연동 (Publish to GitHub)

2단계: 카드 데이터 및 비주얼 시스템 (MVC 구조)

  • 2.1 카드 데이터 정의 (Model): ScriptableObject를 이용한 Card.cs 설계 (이름, 비용, 공/체)
  • 2.2 카드 비주얼 구현 (View): Card_Template 프리팹 제작 및 UI 텍스트 연결
  • 2.3 데이터 반영 (Controller): CardDisplay.cs를 통한 데이터 덮어쓰기 로직
  • 2.4 스프라이트 설정: 외부 이미지를 Sprite (2D and UI) 타입으로 변환 및 적용

3단계: 카드 정렬 및 배치 시스템

  • 3.1 자동 정렬 레이아웃: Horizontal Layout Group을 활용한 손패(Hand)와 필드(Field) 구획 나누기
  • 3.2 레이아웃 그룹 최적화: Control Child Size 해제 및 Padding/Spacing 설정
  • 3.3 핸드 매니저: 게임 시작 시 덱(Deck)의 데이터를 바탕으로 카드를 생성하는 HandManager.cs

4단계: 드래그 앤 드롭 (Drag & Drop) 메커니즘

  • 4.1 마우스 상호작용: IDragHandler, IBeginDragHandler 등을 활용한 CardDraggable.cs 구현
  • 4.2 레이캐스트 차단: Canvas Group을 이용해 드래그 중 마우스 클릭이 카드를 통과하게 만들기
  • 4.3 구역 인식: DropZone.cs를 통한 필드/손패 투착 로직 및 부모 오브젝트 변경

5단계: UI 연출 및 트러블슈팅

  • 5.1 확대 연출 (On Top): 마우스 오버 시 카드가 가장 앞으로 튀어나오게 하는 Sorting Order 제어
  • 5.2 잘림 현상 해결: 마스크(Mask) 컴포넌트 제거 및 캔버스 설정 확인
  • 5.3 피벗(Pivot) 조정: 카드 확대 시 아래쪽이 잘리지 않도록 Pivot Y축을 0으로 설정
  • 5.4 하이어라키 순서 제어: 필드에 카드를 낼 때 위치(Index)가 고정되거나 바뀌는 문제 해결

6단계: 게임 관리 시스템 (Turn Management)

  • 6.1 턴 종료 버튼: 클릭 시 버튼 색상 변경(하얀색 ↔ 노란색) 및 이벤트 연결
  • 6.2 이벤트 시스템: EventSystem 오브젝트 확인 및 Raycast Target 설정법
  • 6.3 에러 디버깅: NullReferenceException 발생 시 프리팹 연결 상태 확인법

 

 

 

 

 


해결됨)

마우스 호버 시 **옆에 있는 카드에 가려지던 문제(레이어 간섭)**를 수정한 핵심 원리는 **"개별 캔버스(Nested Canvas)를 통한 출력 우선순위(Sorting Order) 조절"**입니다.

코드가 아닌 시스템 원리로 설명하면 다음과 같습니다.

1. 문제의 원인 (수정 전)

유니티 UI는 기본적으로 하이어라키(Hierarchy) 목록의 순서대로 화면에 그립니다.

  • 목록 위쪽에 있는 카드를 먼저 그리고, 아래쪽에 있는 카드를 나중에 그립니다.
  • 결과적으로 오른쪽에 있는 카드가 왼쪽 카드보다 아래에 있기 때문에, 왼쪽 카드가 아무리 커져도 오른쪽 카드 밑에 깔리게 되어 "잘린 것처럼" 보였던 것입니다.

2. 해결 방법 (Canvas 컴포넌트 활용)

이 문제를 해결하기 위해 카드 프리팹에 [Canvas] 컴포넌트를 추가했습니다. 이 컴포넌트가 하는 역할은 **"부모의 그리기 규칙을 무시하고 나만의 순서를 정하겠다"**는 선언입니다.

3. 구체적인 수정 과정

  1. 독립된 층 생성: 카드 프리팹에 Canvas를 넣고 Override Sorting 기능을 켰습니다. 이렇게 하면 이제 이 카드는 하이어라키 순서와 상관없이 독립적인 '층(Layer)' 번호를 가질 수 있게 됩니다.
  2. 동적 우선순위 변경 (호버 시):
    • 평소에는 모든 카드의 Sorting Order0입니다. 이때는 원래대로 하이어라키 순서대로 그려집니다.
    • 마우스를 올리는 순간, 그 카드만 Sorting Order를 100으로 확 높여버립니다.
  3. 결과: GPU는 "번호가 높은 100번 카드를 가장 나중에(가장 위에) 그려야지"라고 판단합니다. 따라서 이 카드는 하이어라키 상의 위치는 그대로인데, 화면에서만 다른 모든 카드보다 앞쪽으로 튀어나와 옆 카드들을 덮어버리게 된 것입니다.

 

 

 

 

가려지는거[   ]

하스스톤에서 카드를 확인하려고 마우스를 올렸을 때, 그 카드가 다른 카드들을 모두 제치고 가장 앞으로 튀어나오면서(On Top) 화면을 가득 채우는 연출을 원하시는 거군요.

지금 카드가 다른 카드에 가려지거나 옆이 잘리는 이유는 Horizontal Layout Group이 하수인의 렌더링 순서(Sibling Index)를 강제로 제어하고 있고, 부모 오브젝트의 영역 제한에 걸려 있기 때문입니다.

 

 

 

2. "오른쪽이 잘리는 문제" 해결법 (체크리스트)

마우스를 올려서 카드가 커졌는데 오른쪽 끝이 싹둑 잘려 보인다면, 코드 문제가 아니라 유니티의 Mask(마스크) 설정 때문입니다.

  1. Mask 컴포넌트 확인:
    • PlayerHand PlayerField 오브젝트에 Mask 또는 Rect Mask 2D 컴포넌트가 붙어있는지 확인하세요.
    • 해결: 있다면 삭제하거나 체크 해제하세요. 마스크가 있으면 자식이 부모 영역(분홍색/회색 칸) 밖으로 나가는 순간 잘라버립니다.
  2. Canvas 설정 (프리팹):
    • Card_Template 프리팹에 Canvas 컴포넌트가 반드시 있어야 합니다.
    • Canvas 컴포넌트의 Additional Shader Channels 설정 등이 기본값인지 확인하시고, 무엇보다 CardDraggable 스크립트에서 이 Canvas를 제대로 가져오고 있는지 확인하세요.
  3. 부모의 캔버스 설정:
    • 혹시 최상위 Canvas 오브젝트의 Render Mode Screen Space - Overlay가 아닌가요? Overlay 모드에서 가장자리로 나가면 화면 밖으로 잘리는 게 당연하므로, 카드가 너무 커서 화면 해상도를 넘지 않는지 체크하세요.

3. 유니티 설정 다시 확인하기

지금 상황에서 가장 확실하게 "보고자 하는 카드가 모든 걸 가리고 보이게" 하려면 다음을 수행하세요:

  • Card_Template 프리팹 인스펙터에서:
    1. Canvas 컴포넌트 추가됨 확인.
    2. Graphic Raycaster 컴포넌트 추가됨 확인.
    3. CardDraggable 스크립트 연결됨 확인.
  • PlayerHand 오브젝트에서:
    • Horizontal Layout Group Padding은 원래대로(작게) 돌려놓으세요.
    • Mask 관련 컴포넌트가 절대 없어야 합니다.

 

 

 

 

 

왜 카드가 다른 카드를 가리며 앞으로 안 나오나요?

만약 마우스를 올렸을 때 카드가 커지긴 하는데 옆 카드에 가려진다면, Card_Template 프리팹에 다음 컴포넌트가 있는지 확인하세요.

  1. Canvas 컴포넌트 (스크립트가 canvas.overrideSorting을 제어하기 위해 필수)
  2. Graphic Raycaster 컴포넌트 (Canvas를 넣으면 마우스 클릭을 위해 세트로 필요함)

 

 

 

 

 

 

 

 

 

 

 

 

 


오 해결됨 ㅋ

 

턴종료버튼 눌럿는데 ,

1) 스크립트 연결이 끊겼거나 2) 이미지가 등록되지 않았거나 3) 클릭 이벤트가 호출되지 않는 경우

 

 

 

EventSystem 오브젝트가 있나요? (가장 흔한 원인)

 버튼의 "Raycast Target"이 켜져 있나요?

버튼의 On Click () 리스트

 

 

 


[  ]할거 없으면 초록색으로 되는건, 

마나시스템 구현하고낫 

 

[  ]상대턴 끝나야지 노란색으로 돌아오는건 턴 구현하고나서 

일단은, 클릭하면 노란색됫다가, 다시 하얀색되는거 

 

 

 

 

 

 

남은 단계들

1단계: 턴 관리 시스템 & 턴 종료 효과 (가장 추천)

사용자님이 처음에 말씀하신 **"전장처럼 턴 종료 시 발동하는 효과"**를 구현하는 단계입니다.

  • 할 일: '턴 종료' 버튼을 만들고, 버튼을 누르면 필드에 있는 하수인들이 차례대로 자신의 능력을 실행하게 합니다.
  • 난이도: 쉬움 (기존 하수인 리스트만 훑으면 됨)
  • 재미 요소: "내 턴이 끝날 때 모든 하수인에게 공격력 +1 부여" 같은 전장 식 시너지가 작동하기 시작합니다.

2단계: 마나(코스트) 시스템

하스스톤 정규전의 핵심인 **"자원의 제한"**을 넣는 단계입니다.

  • 할 일: 현재 마나 수정 UI를 만들고, 카드를 낼 때 현재 마나 >= 카드 비용인지 체크합니다. 비용이 부족하면 드래그를 해도 필드에 안 놓아지게 막습니다.
  • 난이도: 매우 쉬움 (단순 숫자 비교)
  • 재미 요소: 무분별하게 카드를 다 내는 게 아니라 전략적으로 고민하게 됩니다.

3단계: 하수인 사망 처리 및 필드 정리

공격력이나 체력이 변하다가 체력이 0이 되면 파괴되는 규칙입니다.

  • 할 일: 하수인의 체력이 0 이하가 되면 필드에서 제거하고 오브젝트를 파괴하는 함수를 만듭니다.
  • 난이도: 보통
  • 재미 요소: 하수인이 사라지고 남은 하수인들이 다시 정렬되는 모습을 보며 게임의 흐름이 생깁니다.

4단계: 기초적인 전투 (공격)

하스스톤처럼 내 하수인으로 적을 때리는 기능입니다.

  • 할 일: 내 필드의 하수인을 클릭하고 적 하수인(혹은 상대 본체 영역)으로 화살표를 끌어 데미지를 주는 로직입니다.
  • 난이도: 보통 (화살표 그리기UI가 조금 번거로울 수 있음)
  • 재미 요소: 드디어 상대를 물리칠 수 있는 수단이 생깁니다.

 

 

 


 

 

 

 

 

[  ]근데 글자크기말고 굵기를 변경하는건 폰트바꾸는거말고는없나 

이건 급한 사항은 아니니깐 

 

[   ]필드에 낸 상태여도 정보보고싶으면 확대되는게 맞으니깐, <근데 그러면 대상으로 지정할떄 문제가 될수도

이거 어떻게 구현하고잇는지 이해해야겟음

 


해결한 문제들, 나중에 미뤄도될것드

 

[  ]코드해석, 이게 어떻게되는건지, 

 

 


[   ]먼소리여

어떻게 구현하고잇는거지 

 

[ 해결 ]왼쪽에 내고싶은데, 현재 horizontal 설정해서 무조건 오른쪽에만 내지는 문제 😀

 

지금 문제는 **"카드를 놓는 순간 부모(Parent)가 바뀌면서 유니티가 자동으로 맨 오른쪽(마지막 자식)으로 보낸 뒤에 인덱스를 설정하려고 하기 때문"**일 가능성이 높습니다.

OnDrop에서 부모를 먼저 바꾸고 나서 인덱스를 설정하는 것입니다.

 

 

 

 

 

 

 

[  ]어떻게 구현되는지도 

"필드에 이미 나간 하수인의 위치를 바꾸지 못하게" 하고, "손패에서 필드로 낼 때만" 드래그가 가능하도록

하스스톤 전장이나 정규전에서 카드를 낼 때 **하수인들이 옆으로 비켜나며 자리를 만들어주는 연출(Shoving)**과, 드래그 중에는 다른 카드가 커지지 않게 하는 기능

 

 

[   ]만약 하수인 여러마리 잇다면, 비켜나게 되어야하는데, 젤 끝에만 낼수있어야하는건 아니니깐 😀

  1. 동작 원리:
    • 카드를 잡는 순간, 그 카드와 똑같은 크기의 **투명한 상자(Placeholder)**가 생깁니다.
    • 마우스를 필드 위로 가져가면 이 투명한 상자가 필드 자식으로 들어갑니다.
    • 필드의 Horizontal Layout Group은 이 투명한 상자도 하수인으로 인식하여 옆으로 비켜나 자리를 만들어줍니다.
    • 마우스를 떼면 카드가 투명 상자가 있던 자리에 쏙 들어갑니다.
  2. 호버 방지:
    • CardDraggable.isDraggingAnyCard true일 때는 모든 카드의 OnPointerEnter가 작동하지 않으므로, 필드 하수인들이 드래그 중에 번쩍거리며 커지는 현상이 사라집니다.
  3. 로그 확인:
    • 카드를 낼 때 필드 하수인들이 좌우로 슥슥 움직이는지 확인하세요.
    • 손패에서 카드를 쥐고 필드 위를 돌아다녀도 필드 카드가 반응하지 않아야 합니다.

 

 

 


[  ] 하수인 잘리는 문제 

걍 화면 크게하면 해결됨 

 

 

[   ]필드에 낸 상태여도 정보보고싶으면 확대되는게 맞으니깐, <근데 그러면 대상으로 지정할떄 문제가 될수도


 

 

 

 

 

 

1단계: 유니티 프로젝트 생성 및 화면 설정

  1. Unity Hub에서 2D Core 템플릿으로 프로젝트를 만듭니다.
  2. 상단 메뉴 Window > General > Game 창을 켜서 화면 비율을 16:9 (또는 1920x1080)로 고정합니다. (하스스톤 비율)

걍 여기서 해도됨

 

 

2단계: 게임판 구획 나누기 (UI 레이아웃)

하스스톤의 판을 머릿속으로 그리며 '영역'을 나눕니다.

  1. Hierarchy(계층 구조) 창에서 우클릭 -> UI > Canvas를 만듭니다. (모든 UI의 부모입니다.)
  2. Canvas 안에 우클릭 -> Create Empty를 눌러 4개의 빈 오브젝트를 만들고 이름을 다음과 같이 정하세요.
    • EnemyField: 상대방 하수인들이 놓일 자리 (화면 상단)
    • PlayerField: 내 하수인들이 놓일 자리 (화면 중간)
    • PlayerHand: 내 손패 카드가 있을 자리 (화면 하단)
    • TurnEndButton: 턴 종료 버튼 (화면 오른쪽)

 

팁: 각 영역이 어디인지 눈에 보이게 하려면, 각 오브젝트에 UI > Image를 추가하고 색깔을 투명하게(회색 등) 깔아두면 구분이 편합니다.

 

Create Empty로 만들면 화면에 아무것도 안 보여서 막막한 게 당연합니다. **"영역"**을 눈에 보이게 만들고 크기를 조절하려면 두 가지 방법이 있습니다.

추천 방법: "Image" 컴포넌트 추가하기 (눈에 보여야 편합니다)

  1. Hierarchy 창에서 만든 EnemyField를 선택합니다.
  2. 오른쪽 Inspector 창에서 Add Component 버튼을 누르고 Image를 검색해서 추가합니다.
    • 이제 화면에 하얀 네모가 나타날 거예요!
    • Color 칸을 눌러서 색상을 어둡게 하고, Alpha(A) 값을 낮추면(예: 50) 반투명해져서 배경처럼 쓰기 좋습니다.

영역 크기 조절하기 (Rect Tool 사용)

  1. 왼쪽 상단 툴바에서 **네모 모양 아이콘 (Rect Tool, 단축키 T)**을 누르세요.
  2. 이제 화면(Scene 뷰)에 보이는 하얀 네모의 모서리를 마우스로 잡고 늘릴 수 있습니다.
    • EnemyField: 화면 위쪽 절반 정도 차지하게 배치.
    • PlayerField: 화면 중간에 가로로 길게 배치.
    • PlayerHand: 화면 맨 아래쪽에 배치.

[  ]일단 상대방 패는, 좀 나중에 할까나 

 

 

 

 

 

 

 

3단계: "카드" 한 장의 생김새 만들기 (Prefab)

이제 카드의 '껍데기'를 만듭니다.

  1. Canvas 안에 UI > Image를 하나 만듭니다. (이름: Card_Template)
    • 크기를 카드 비율(예: 가로 150, 세로 220)로 조절합니다.
  2. Card_Template의 자식으로 다음 내용들을 추가합니다 (UI > Legacy > Text 또는 TextMeshPro 사용):
    • CostText: 왼쪽 위 (마나 수정)
    • NameText: 중간 위 (카드 이름)
    • DescriptionText: 중간 아래 (카드 설명 - "턴 종료 시 +1/+1" 등)
    • AttackText: 왼쪽 아래 (공격력)
    • HealthText: 오른쪽 아래 (체력)
  3. 다 만드셨다면, 이 Card_Template 오브젝트를 **Project 창(폴더창)**으로 드래그 앤 드롭 하세요.
    • 그러면 파란색 아이콘의 **Prefab(프리팹)**이 됩니다. 이제 이걸 무한복제해서 쓸 수 있습니다.

 

 

 

 

 

(이거 화면 크기조절하니깐, 화면이 작아지던 이유가 )

 

 

네, 화면을 보니 확실히 지금의 Card_Template이 전체 판에 비해 크게 느껴지네요!

그 이유는 Canvas Scaler(캔버스 스케일러) 설정 때문일 확률이 높습니다. 하스스톤 같은 게임은 화면 크기가 바뀌어도 카드의 비율이 일정하게 유지되어야 하거든요.

우선 크기를 조정하기 전에 기준점부터 잡아봅시다.


1. 화면 기준점 설정 (매우 중요!)

  1. Hierarchy 창에서 Canvas를 클릭하세요.
  2. Inspector 창에 있는 Canvas Scaler 컴포넌트를 찾으세요.
  3. UI Scale ModeScale With Screen Size로 바꾸세요.
  4. Reference Resolution1920 x 1080으로 적으세요. (이게 국룰입니다.)
  5. 그 아래 Match 바를 0.5로 끝까지 당기세요.

결과: 이제 화면이 커지거나 작아져도 우리가 설정한 비율대로 유지됩니다. 아마 이 설정을 하면 카드가 갑자기 작아 보일 수도 있는데, 그때 다시 크기를 조절하면 됩니다.


2. 카드 크기 다시 잡기

150, 220이 크다고 느껴진다면, 눈대중으로 직접 줄이는 게 제일 정확합니다.

  1. Card_Template을 선택합니다.
  2. 단축키 T (Rect Tool)를 누릅니다.
  3. 파란색 점을 잡고 줄여서 **"내 패(PlayerHand)에 7~10장이 들어가도 괜찮을 정도"**의 크기로 만들어보세요.
    • (참고: 대략 Width 100120, Height 140170 정도가 적당할 수 있습니다.)

이정도 크기 ㄱㅊ은듯

 


3. 카드 내부에 텍스트 넣기 (미리 해두면 좋습니다)

카드가 너무 휑하면 크기 가늠이 안 됩니다. Card_Template의 자식으로 텍스트들을 넣어주세요.

  1. Card_Template 우클릭 -> UI > Legacy > Text (또는 TextMeshPro)를 만듭니다.
  2. 이름: CostText -> 왼쪽 위 배치 (숫자 '1' 입력)
  3. 이름: AttackText -> 왼쪽 아래 배치 (숫자 '1' 입력)
  4. 이름: HealthText -> 오른쪽 아래 배치 (숫자 '1' 입력)
  5. 이름: NameText -> 가운데 위 배치 (글자 '하수인' 입력)

꿀팁: 텍스트를 배치할 때 Anchor(앵커) 설정을 카드 구석에 맞춰두면, 나중에 카드 전체 크기를 늘리거나 줄여도 글자들이 구석에 잘 붙어있게 됩니다.

 

 

 

 

 

 

 

 

  1. 배치가 끝나면 Card_Template을 하단 Project 창으로 드래그해서 Prefab으로 만든다.
  2. 화면(Hierarchy)에 남아있는 Card_Template은 삭제한다.

 

오 그럴듯한데 

 

오히려 글자가 아예 없으면 나중에 코딩할 때 어디에 뭐가 들어가는지 알기 어렵거든요. 지금 넣으신 "잠꾸러기 투사", "비용", "4", "10" 같은 것들은 '가이드라인(Placeholder)' 역할을 하게 됩니다.

나중에 게임이 시작되면 코드가 이 글자들을 "실제 카드 이름"이나 "실제 공격력"으로 덮어쓰게 될 거예요.

[  ]어떤 원리로 덮어씌워지게 되는걸까

 

 

  1. 계층 구조(Hierarchy) 순서:
    • Card_Template (부모)
      • card_image (이게 가장 위에 있어야 배경처럼 깔끔합니다. 글자보다 뒤에 보이게 하려면 목록에서 위쪽에 두세요.)
      • CostText, NameText 등 (글자들은 목록 아래쪽에 두어야 이미지 위로 글씨가 보입니다.)
  1. 텍스트 정렬:
    • 각 텍스트의 Inspector 창에서 Paragraph > Alignment를 중앙 정렬로 맞추면 나중에 글자 수가 바뀌어도 예쁘게 보입니다.

 

아직 프리팹 폴더의 모습이 안보이는 상황 

 

  1. 자동 인식 여부: 유니티가 특정 폴더를 "여긴 무조건 프리팹만 들어가는 곳이야"라고 자동으로 인식하지는 않습니다. 하지만 사용자가 Hierarchy에 있는 물체를 어떤 폴더든 'Project 창'으로 끌어다 놓는 순간, 유니티는 "아, 이걸 원본(Prefab)으로 만들고 싶구나!"라고 인식해서 저장합니다.
  2. 왜 폴더를 만드나요? 나중에 카드뿐만 아니라 이펙트, 버튼, 캐릭터 등 수십 개의 프리팹이 생기면 찾기가 너무 힘들어지기 때문입니다.

 

 

 

 

 

4단계: 자동으로 정렬되게 만들기 (핵심 기능)

카드를 한 장씩 배치하기 힘드니까 유니티의 '자동 정렬' 기능을 씁니다.

  1. 아까 만든 PlayerHandPlayerField, EnemyField 오브젝트를 선택합니다.
  2. Inspector(검사) 창에서 Add Component를 누르고 **"Horizontal Layout Group"**을 검색해서 추가합니다.
  3. 그 안의 옵션에서 Child AlignmentMiddle Center로 바꿉니다.
  4. 확인 작업: 이제 아까 만든 Card_Template 프리팹을 PlayerHand 오브젝트 안으로 막 끌어다 넣어보세요. 카드가 옆으로 촤르륵 자동으로 퍼진다면 성공입니다!

 

 

 

 

 

1. Card 스크립트의 역할: "데이터 (신분증)"

이 스크립트는 카드가 가진 정보 그 자체를 정의합니다. 화면에 어떻게 보일지는 관심이 없고, 오로지 숫자와 글자만 기억합니다.

  • 포함될 정보: 카드 이름, 마나 비용, 공격력, 체력, 카드 설명.
  • 특징: 유니티의 ScriptableObject라는 기능을 사용하면, 엑셀처럼 여러 장의 카드를 파일 형태로 미리 만들어둘 수 있습니다. (예: '잠꾸러기 투사.asset', '단검 곡예사.asset' 등)

2. CardDisplay 스크립트의 역할: "비주얼 (전광판)"

이 스크립트는 **프리팹(우리가 만든 카드 틀)**에 붙어서, Card가 가진 정보를 읽어와 실제 화면(텍스트, 이미지)에 뿌려주는 역할을 합니다.

  • 수행하는 일:
    • Card 데이터에서 '공격력 4'를 읽어옴.
    • 카드의 AttackText 글자를 '4'로 바꿈.
    • 전장 스타일 효과가 있다면, 턴 종료 시 로직을 실행함.

 

 

 

 

 

 

비주얼 스튜디오 코드에서 깃허브 연계 

이거말고

 

둘중 뭐클릭하지 

 

 

 

 

 

 

이 두 버튼은 **"내 컴퓨터에만 저장할래? 아니면 바로 깃허브에 올릴래?"**의 차이입니다.

결론부터 말씀드리면, **[Publish to GitHub]**를 누르는 것이 훨씬 편합니다!


1. 버튼 설명

  • Initialize Repository: 내 컴퓨터(로컬)에서만 버전 관리를 시작합니다. 깃허브랑 연결은 나중에 따로 설정해야 합니다.
  • Publish to GitHub (추천): "내 컴퓨터에 깃 저장소 만들기 + 깃허브에 저장소 만들기 + 업로드"를 한 번에 다 해줍니다. 인텔리J에서 하던 방식과 가장 비슷합니다.

⚠️ 잠깐! 누르기 전에 꼭 해야 할 일 (매우 중요)

유니티 프로젝트를 그냥 올리면 Library, Temp 같은 무거운 쓰레기 파일들이 같이 올라가서 깃허브가 금방 꽉 차거나 오류가 납니다. **.gitignore**라는 파일을 먼저 만들어야 합니다.

방법:

  1. 왼쪽 첫 번째 아이콘(파일 목록)으로 돌아가서 Assets 폴더 바깥 빈 공간을 우클릭합니다.
  2. **[New File]**을 누르고 이름을 정확히 .gitignore 라고 짓습니다 (앞에 점이 붙어야 해요).
  3. 구글에서 Unity gitignore를 검색해서 나오는 내용이나, 아래 링크의 내용을 복사해서 그 파일에 붙여넣고 저장하세요.

2. 이제 올리는 순서

위의 .gitignore 파일을 만들었다면, 다시 깃 메뉴로 돌아와서 **[Publish to GitHub]**를 누르세요.

  1. 로그인 요청: 브라우저가 뜨면서 깃허브 로그인을 하라고 하면 승인(Allow)을 해줍니다.
  2. 공개 여부 선택:
    • Publish to GitHub public repository: 전 세계에 공개
    • Publish to GitHub private repository: 나만 보기 (보통 이걸 추천합니다)
  3. 파일 선택: 올릴 파일들을 선택하라고 뜨는데, 그냥 다 체크된 상태로 **[OK]**를 누르시면 됩니다. (.gitignore가 있다면 알아서 필요한 것만 올라갑니다.)

요약

".gitignore 파일부터 만들고 나서 -> [Publish to GitHub]를 누르세요!"

이렇게 하면 인텔리J처럼 비주얼 스튜디오 코드에서도 깃허브 관리가 완벽하게 시작됩니다. 다 되시면 아래쪽 상태 표시줄에 깃허브 아이콘이 뜰 거예요!

 

 

 

 

 

(프로젝트 최상위 폴더인 MYHARTHSTONE2 바로 아래)에 있어야 됨

폴더말고, 파일이어야함 

 

 

  • /[Ll]ibrary/, /[Tt]emp/: 유니티가 내부적으로 쓰는 임시 파일들인데, 용량이 엄청 크고 내 컴퓨터에서만 필요한 것들이라 깃허브에 올릴 필요가 없습니다.
  • *.csproj, *.sln: 비주얼 스튜디오 설정 파일들인데, 이것도 깃허브에 올리면 다른 사람(혹은 다른 컴퓨터)에서 열 때 충돌이 날 수 있어서 제외합니다.

 

 

 

혼자서만 작업하신다면 사실 "No"를 눌러도 아무 상관 없습니다. 굳이 켤 필요가 없는 기능이 되거든요.

그 이유를 아주 쉽게 설명해 드릴게요.

1. 왜 혼자 할 때는 필요 없나요?

git fetch는 "서버(GitHub 등)에 남이 올린 새로운 코드가 있는지" 확인하는 기능입니다.

  • 팀 작업 시: 동료가 코드를 올리면 나한테 알려줘야 하니까 필요함.
  • 나 혼자 작업 시: 내가 코드를 올리지 않는 이상 서버의 코드가 바뀔 일이 없음. (내가 이미 내 코드를 알고 있으니 확인이 필요 없음)

2. 하지만 '혼자'라도 이런 경우에는 "Yes"가 편합니다

혼자 작업하더라도 컴퓨터를 여러 대 쓰신다면 유용합니다.

  • 예를 들어, 집 데스크탑에서 작업해서 올리고, 나중에 카페 노트북으로 VS Code를 켰을 때:
    • "Yes"를 해뒀다면: 노트북을 켜자마자 "집에서 작업한 내용이 있으니 가져오세요"라고 알려줍니다.
    • "No"를 했다면: 내가 직접 확인해보기 전까지는 서버에 새 내용이 있는지 모릅니다.

또한, GitHub 웹사이트에서 직접 파일을 수정하거나 리드미(README)를 고치는 경우에도 자동으로 알려주기 때문에 편리합니다.

결론 (추천)

  • 컴퓨터 한 대만 쓰고, GitHub 사이트에서도 직접 수정 안 한다: 그냥 "No" 누르세요. 신경 안 쓰셔도 됩니다.
  • 집/회사(노트북)를 왔다 갔다 하며 작업한다: **"Yes"**를 누르는 게 훨씬 편합니다.

한 줄 요약:
진짜로 딱 컴퓨터 한 대에서만 혼자 작업하신다면 아무 쓸모 없는 기능이니 No 하셔도 됩니다!

 

 

 

 

 

"데이터 파일(.asset)"은 카드 종류만큼 만들어야 하지만, "스크립트(.cs)"는 딱 하나씩만 있으면 됩니다.

 

 

 

 

 

 

 

 

코드를 넣은 후 유니티에서 해야 할 일

  1. 데이터 파일 만들기:
    • Assets 폴더 빈 곳에 우클릭 -> Create -> CardSystem -> Card를 누르세요.
    • 파일 이름을 'Slacker'로 짓고, 오른쪽 Inspector 창에서 이름 '잠꾸러기 투사', 공격력 4, 체력 10 등을 입력해보세요. (이게 진짜 카드 데이터입니다!)
  2. 프리팹에 스크립트 붙이기:
    • Prefabs 폴더에 있는 Card_Template 프리팹을 더블 클릭해서 엽니다.
    • Add Component를 눌러 CardDisplay를 검색해서 추가합니다.
    • 스크립트 칸에 빈 구멍들(Name Text, Cost Text 등)이 보일 겁니다.
    • 자식으로 있는 TMP 오브젝트들을 그 구멍에 하나씩 드래그해서 연결해주세요.
    • 마지막으로 Card Data 칸에 방금 만든 'Slacker' 파일을 넣어보세요.

 

 

나중에 카드가 30장, 50장으로 늘어나면 폴더 없이 관리하기가 매우 힘들어집니다. 아래와 같이 폴더를 구성하는 것을 추천드려요.

1. 추천 폴더 구조

  • Assets
    • Scripts (코드들)
    • Prefabs (카드 틀 원본)
    • Cards (여기에 실제 카드 데이터들을 모아둘 겁니다) <- 새로 만드세요!

2. 왜 인식을 걱정하지 않아도 되나요?

유니티의 ScriptableObject(우리가 만든 Card 스크립트 방식)는 파일 자체에 고유한 ID가 부여됩니다. 따라서:

  • 폴더 이름을 바꿔도 괜찮습니다.
  • 폴더를 이동시켜도 괜찮습니다.
  • 코드가 "이 파일을 써라"라고 한 번 연결만 되면, 그 파일이 어디로 이사를 가든 유니티가 끝까지 쫓아가서 찾아냅니다.

 

 

 

 

 

메모장이나 비주얼 스튜디오에서 코드를 입력한 뒤 **Ctrl + S (저장)**를 누르지 않으면 유니티는 코드가 바뀐 걸 모릅니다.

  • 해결법: 코드 편집기(Visual Studio 등)로 돌아가서 Card.cs 파일을 저장하고 유니티로 돌아오세요. 유니티 오른쪽 하단에 로딩 아이콘(동그라미)이 돌아가면서 컴파일을 합니다.

 

 

 

 

 

  • Wrapping: Enabled (체크되어 있어야 줄바꿈이 됩니다.)

 

 

 

 

근데 손패에 잇을때랑 필드에 잇을때 좀 다른모습이네 

 

 

 

외부에서 이미지를 다운로드하거나 직접 그려서 Sprites 폴더에 넣으면, 유니티가 처음에는 그냥 '일반 이미지'로 인식합니다. 이걸 카드 UI에 쓰려면 설정을 바꿔줘야 합니다.

  1. 폴더에 넣은 이미지 파일을 클릭합니다.
  2. 오른쪽 Inspector 창 맨 위에 있는 Texture Type을 확인합니다.
  3. 이걸 **Sprite (2D and UI)**로 변경합니다.
  4. 맨 아래 [Apply] 버튼을 누릅니다.
    • 이렇게 해야만 카드 프리팹의 Image 칸이나 Card 데이터의 artwork 칸에 넣을 수 있게 됩니다.

 

 

[  ]이해

  • Card_Template 프리팹을 열고 **Add Component -> Canvas Group**을 추가합니다. (이게 있어야 드래그 중 마우스 클릭이 카드를 뚫고 바닥을 인식할 수 있습니다.)

 

 

코드작성후, 

 

 

유니티 에디터 설정 

  1. HandManager 설정:
    • Canvas에 HandManager를 붙입니다.
    • Card Prefab 칸에 Card_Template 프리팹을 넣습니다.
    • Hand Parent 칸에 PlayerHand 오브젝트를 드래그해서 넣습니다.
    • Deck 리스트의 + 버튼을 눌러 아까 만든 Slacker, Khadgar 등 카드 데이터(SO)들을 쭉 넣습니다.
  2. 프리팹 설정:
    • Card_Template 프리팹에 CardDraggable 스크립트를 붙입니다. (Canvas Group도 있는지 꼭 확인!)
  3. 영역 설정:
    • PlayerField PlayerHand 오브젝트에 각각 DropZone 스크립트를 붙입니다.
    • 주의: 두 오브젝트 모두 Image 컴포넌트가 있어야 하고, Raycast Target이 체크되어 있어야 마우스를 인식합니다.

 

 

 

 

 

 

 

 

 

유니티 에디터 설정은 처음 하면 클릭 한 번, 드래그 한 번이 다 생소할 수 있습니다. 아주 구체적으로 하나씩 짚어드릴게요.

1. HandManager 설정 (데이터 연결)

  1. Hierarchy(계층 구조) 창에서 Canvas 오브젝트를 클릭합니다.
  2. Project(폴더) 창에서 아까 만든 HandManager 스크립트를 마우스로 잡고, Canvas의 Inspector(오른쪽 창) 빈 곳에 드롭합니다. (스크립트가 컴포넌트로 붙습니다.)
  3. Inspector 창에 생긴 Hand Manager 항목을 보세요. 3개의 빈 칸이 있을 겁니다.
    • Card Prefab: Prefabs 폴더에 있는 Card_Template을 마우스로 끌어서 이 칸에 넣으세요.
    • Hand Parent: Hierarchy에 있는 PlayerHand 오브젝트를 마우스로 끌어서 이 칸에 넣으세요.
    • Deck: Deck 글자 왼쪽의 작은 화살표를 눌러 펼친 후, Size 칸에 숫자 2를 적고 Enter를 누릅니다. (카드가 2장이면 2)
    • 그 아래 생긴 Element 0, Element 1 칸에 각각 아까 Cards 폴더에 만든 SlackerKhadgar 파일을 하나씩 드래그해서 넣으세요.

2. 카드 프리팹(Card_Template) 설정

  1. Project 창의 Prefabs 폴더에서 Card_Template더블 클릭합니다. (프리팹 편집 화면으로 들어갑니다.)
  2. 오른쪽 Inspector 창 아래쪽의 Add Component 버튼을 누릅니다.
  3. **"CardDraggable"**을 검색해서 추가합니다.
  4. 한 번 더 Add Component를 눌러 **"Canvas Group"**을 검색해서 추가합니다.
    • 이게 없으면 드래그하는 동안 카드가 마우스를 가로막아 "이곳이 필드다!"라는 걸 인식을 못 합니다.
  5. 왼쪽 상단의 <- (뒤로가기) 버튼을 눌러 원래 화면으로 돌아옵니다.

3. 영역(DropZone) 설정

  1. Hierarchy 창에서 PlayerHand 오브젝트를 클릭합니다.
  2. Inspector 창에서 Add Component -> DropZone 스크립트를 추가합니다.
  3. Hierarchy 창에서 PlayerField 오브젝트를 클릭합니다.
  4. Inspector 창에서 Add Component -> DropZone 스크립트를 추가합니다.

※ 매우 중요한 체크포인트 (안 되면 여기 확인):

  • PlayerHandPlayerFieldImage 컴포넌트가 있나요? (색깔이 있고 눈에 보여야 합니다.)
  • 그 Image 컴포넌트 안에 Raycast Target이라는 체크박스가 체크되어 있나요?
    • 이게 체크 안 되어 있으면 마우스가 "여기가 바닥이구나"라고 느끼질 못합니다.

4. 마지막 확인 작업

  • 이제 화면 상단 중앙의 [▶] (Play) 버튼을 눌러보세요.
  • 성공 시: 게임이 시작되자마자 PlayerHand 영역에 아까 Deck에 넣은 카드 2장이 촥 나타납니다.
  • 드래그 테스트: 카드를 마우스 왼쪽 버튼으로 꾹 눌러서 끌어보세요. 카드가 마우스를 따라오나요?
  • 드롭 테스트: 카드를 PlayerField(중간 영역) 위로 가져가서 마우스를 떼보세요. 카드가 필드 자식으로 들어가면서 정렬되나요?

만약 여기서 카드가 안 나타나거나, 드래그가 안 된다면?
유니티 화면 아래쪽 Console 탭을 클릭해서 빨간색 에러 메세지가 있는지 확인해주세요. 에러가 있다면 그 내용을 복사해서 알려주시면 바로 해결해 드릴 수 있습니다!

 

 

 

NullReferenceException: Object reference not set to an instance of an object
HandManager.Start () (at Assets/Scripts/HandManager.cs:17)

 

 

 

근데 덱에 어떤 카드들이 잇는지 어떻게 판단하는거지 [  ]

 

 

 

 

 

 

NullReferenceException은 유니티 개발을 하면서 가장 자주 보게 될 에러입니다.

**"빈 상자(null)를 열려고 시도했다"**는 뜻인데, HandManager.cs의 17번째 줄을 보면 display.cardData = cardData; 부분입니다. 여기서 display가 비어있거나 cardData가 비어있을 확률이 높습니다.

아래 3가지를 순서대로 확인해 보세요. 금방 고칠 수 있습니다!


1. [가장 유력] 카드 프리팹에 스크립트가 빠졌나요?

display 변수가 null이라는 뜻은, 생성된 카드 오브젝트에서 CardDisplay 스크립트를 찾지 못했다는 뜻입니다.

  • 확인 방법: Prefabs 폴더에 있는 Card_Template 프리팹을 클릭합니다.
  • 해결 방법: Inspector 창에 Card Display 스크립트가 붙어 있는지 확인하세요. 만약 없다면 Add Component로 추가해줘야 합니다.

2. [두 번째] Deck 리스트에 빈 칸(None)이 있나요?

deck 리스트 안에 실제 카드 파일이 아닌 '빈 칸'이 들어가 있을 때 발생합니다.

  • 확인 방법: Hierarchy에서 HandManager가 붙은 Canvas를 클릭합니다.
  • 해결 방법: Inspector의 Deck 리스트를 펼쳐보세요. Element 0, Element 1 등에 None (Card) 이라고 써진 빈 칸이 있나요? 있다면 그 칸에 아까 만든 카드 데이터 파일을 꼭 넣어주거나, 필요 없는 칸은 삭제해야 합니다.

3. 코드의 안전장치 추가 (에러 방지용)

어디가 문제인지 정확히 찾기 위해 HandManager.cs 코드를 아래와 같이 조금 더 똑똑하게 수정해 보겠습니다. 기존 Start 함수 내용을 지우고 이걸로 덮어씌워 보세요.

    void Start()
{
    foreach (Card cardData in deck)
    {
        // 1. 카드 데이터 자체가 비어있는지 확인
        if (cardData == null) {
            Debug.LogError("Deck에 비어있는 칸이 있습니다!");
            continue; 
        }

        GameObject cardObj = Instantiate(cardPrefab, handParent);
        CardDisplay display = cardObj.GetComponent<CardDisplay>();

        // 2. 프리팹에 CardDisplay 스크립트가 있는지 확인
        if (display != null)
        {
            display.cardData = cardData;
            display.UpdateUI();
        }
        else
        {
            Debug.LogError("카드 프리팹에 CardDisplay 스크립트가 붙어있지 않습니다!");
        }
    }
}
  

 

 

 

 

1. Parent To Return To는 비워둬도 되나요?

네, 비워두셔도 됩니다.
이 칸은 카드가 드래그를 시작할 때, 코드(CardDraggable.cs)가 스스로 채우는 칸입니다.

  • 드래그 시작: "지금 내 부모(손패)가 누구지?" 하고 저 칸에 스스로 저장합니다.
  • 드래그 종료: "아까 저장해둔 부모(또는 새로 결정된 필드)로 돌아가야지!" 하고 사용합니다.
  • 즉, 인스펙터에서 우리가 손댈 필요가 없는 '작업용 메모장' 같은 칸입니다.

2. 카드 7장이면 7번 다 드래그해서 연결해야 하나요? (프리팹의 마법)

아니요! 딱 한 번만 하면 됩니다.
여기서 **프리팹(Prefab)**의 개념이 중요합니다.

  1. **원본(Card_Template)**에서 Name Text, Cost Text 등을 자식 오브젝트들로 연결해 둡니다.
  2. 그러면 HandManager가 카드를 100장 복사(Instantiate)하더라도, 복사본들은 각자 자기 몸 안에 있는 텍스트들을 이미 알고 있는 상태로 태어납니다.
  3. 우리는 HandManager에 있는 Deck 리스트에 **Cards 폴더의 데이터(SO)**만 슉슉 추가해 주면 됩니다. 그러면 그 데이터들이 각 복사본의 cardData 칸에 들어가면서 글자가 바뀌는 방식입니다.

3. "그냥 Cards 폴더에 있는 거 리스트로 넣으면 안 되나요?"

이미 그렇게 하고 계신 겁니다!
아까 만든 HandManager public List<Card> deck;이 바로 그 역할을 합니다.

  • 현재 구조:
    1. Cards 폴더: 실제 카드 데이터들(SO)이 있음.
    2. HandManager: 이 데이터들을 리스트로 가지고 있음. (인스펙터에서 + 눌러서 추가한 것)
    3. 실행 시: HandManager가 리스트에 있는 개수만큼 프리팹을 찍어내고, 폴더에 있는 데이터를 하나씩 꽂아줍니다.

 

 

 

 

 

 

 

 

Card_Template 프리팹에 Card Display 스크립트가 빠져 있습니다.

지금 인스펙터 창을 보면 Image, Canvas Group, Card Draggable은 있는데, 우리가 가장 처음에 만들었던 Card Display 스크립트가 보이지 않습니다. 그래서 코드가 "카드의 글자들을 바꿔라!"라고 명령을 내리려는데, 바꿀 대상(스크립트)이 없어서 에러가 난 것입니다.

해결 방법 (순서대로 따라하세요)

  1. 스크립트 추가:
    • 지금 열려 있는 Card_Template 인스펙터 창 하단의 Add Component 버튼을 누릅니다.
    • Card Display를 검색해서 추가하세요.
  2. 빈 칸 채우기 (연결):
    • Card Display를 추가하면 Name Text, Cost Text, Attack Text 등 빈 칸들이 생길 겁니다.
    • Card_Template 자식으로 만들어둔 텍스트(TMP) 오브젝트들을 각각 이름에 맞는 칸에 드래그해서 넣어주세요. (이걸 안 하면 글자가 안 바뀝니다!)
  3. 데이터 연결 (선택 사항):
    • Card Data 칸은 비워두셔도 됩니다. (어차피 게임 시작할 때 HandManager가 덱에서 카드를 꺼내서 채워줄 거니까요.)
  4. 확인:
    • 다시 상단의 [▶] (Play) 버튼을 눌러보세요.

이제 에러가 사라지고 손패에 카드들이 나타날 겁니다!

성공적으로 카드가 나타나면, 이제 마우스로 카드를 잡고 중간의 필드 영역으로 옮겨보세요. 전장이나 하스스톤처럼 카드가 필드에 딱 고정되는지 확인해 보시기 바랍니다! 잘 되나요?

 

 

 

 

 

HandManager 스크립트는 아마도 Canvas 오브젝트

 

 

 

 

너무 작게보이는데, 카드 크기 좀 키워도되려나 

 

 

 

 

카드가 너무 작거나 구석에 있는 문제 (UI 정렬)

화면을 보면 카드가 분홍색 영역의 왼쪽 구석에 아주 작게 붙어 있습니다. 이건 Horizontal Layout Group 설정 때문입니다.

  1. Hierarchy에서 PlayerHand를 클릭합니다.
  2. 인스펙터의 Horizontal Layout Group에서 다음을 확인하세요:
    • Child Control Size: Width와 Height를 둘 다 체크 해제해 보세요. (카드가 원래 크기로 돌아옵니다.)
    • Child Alignment: Middle Center로 설정하세요. (카드가 가운데로 옵니다.)
  3. PlayerField(회색 영역)도 똑같이 설정해 주세요.

 

 

 

좀 카드 크기 키워야할지도 

 

 

이 컴포넌트가 없으면 카드를 여러 장 손패에 넣어도 한 자리에 겹치거나, 지금처럼 구석에 작게 박혀 있게 됩니다. 하스스톤처럼 카드가 나란히 줄을 서게 하려면 이 컴포넌트가 꼭 필요합니다.

 

 

 

 

 

 

 

 

컴포넌트 추가 및 설정

  1. PlayerHand 오브젝트가 선택된 상태에서 오른쪽 인스펙터 창 하단의 [Add Component] 버튼을 누릅니다.
  2. **"Horizontal Layout Group"**을 검색해서 추가합니다.
  3. 추가된 후, 아래와 같이 설정을 변경하세요 (매우 중요):
    • Padding: Left 20, Right 20 (양 끝 여백입니다.)
    • Spacing: 10~20 (카드와 카드 사이의 간격입니다.)
    • Child Alignment: Middle Center로 바꿉니다. (그래야 카드가 손패 중앙에 옵니다.)
    • Control Child Size: Width와 Height 둘 다 체크를 해제하세요. (이걸 체크하면 카드가 손패 크기에 맞춰 강제로 늘어납니다. 해제해야 우리가 만든 카드 크기가 유지됩니다.)
    • Child Force Expand: Width와 Height 둘 다 체크를 해제하세요. (이게 체크되어 있으면 카드가 한 장일 때 손패 전체를 다 차지하려고 합니다.)

 

 

 

 

 

 

 

 

 

너무 카드가 작은 문제 

 

 

 

 

 

 

필드용/손패용 UI 다르게 하기 (나중 단계지만 팁)

나중에는 카드가 필드에 나가는 순간 설명창(DescriptionText)만 비활성화(SetActive(false)) 시키면 됩니다. 그러면 하수인 그림과 공/체만 남아서 깔끔해지죠. (지금은 일단 다 보이게 가시죠!)

 

 

 

 

꿀팁: 필드에 나가면 마나 수정 숨기기

나중에 드래그가 끝나서 카드가 필드에 놓일 때, 아래 코드를 한 줄 실행해주면 훨씬 게임다워집니다.

// 필드에 놓였을 때 실행할 코드 (예시)
costImage.gameObject.SetActive(false); // 마나 수정 이미지 숨기기
costText.gameObject.SetActive(false);  // 마나 숫자 숨기기

 

 

 

 

 

 

 

 

카드가 겹치거나 위치가 갑자기 바뀌는 이유는 유니티의 Horizontal Layout Group 때문입니다. SetAsLastSibling()을 호출하면 카드의 순서가 맨 뒤로 밀리는데, 레이아웃 그룹은 그 순서를 "오른쪽 끝 위치"로 인식해서 카드를 순간이동 시켜버립니다.

이 문제를 해결하려면 Canvas 컴포넌트를 이용해 순서(Index)를 바꾸지 않고 **출력 우선순위(Sorting Order)**만 높여야 합니다.

 

 

 

 

[   ]그리고 좀더 크게 만들되, 밑으로 안잘리도록

 

 

 

 

 

카드가 아래로 잘리는 문제는 Pivot(피벗) 위치와 관련이 있습니다. 피벗이 중앙(0.5)에 있으면 카드가 상하좌우 모든 방향으로 커지기 때문에 아래쪽이 바닥을 뚫고 나가게 됩니다.

이를 해결하려면 피벗을 아래쪽(Y=0)으로 설정하고, 코드에서 배율을 조절할 수 있도록 변수화해야 합니다.


1단계: 유니티 에디터 설정 (반드시 먼저 하세요!)

  1. Card_Template 프리팹을 더블 클릭해서 엽니다.
  2. 가장 상위 오브젝트인 Card_Template Rect Transform에서 Pivot 값을 찾으세요.
  3. Y 값을 0으로 바꿉니다. (X는 0.5 그대로 둡니다.)
    • 주의: 피벗을 바꾸면 카드가 위로 붕 뜰 수 있습니다. 다시 드래그해서 분홍색 손패 영역 안에 예쁘게 위치를 맞춰주세요.
  4. 이제 카드는 아래쪽을 고정한 채 위로만 커지게 됩니다.

 

 

 

 

 

 

 

 

이 문제는 유니티의 Horizontal Layout Group이 하이어라키(Hierarchy) 창의 **위에서 아래 순서(Sibling Index)**대로만 카드를 배치하기 때문에 발생합니다.

하스스톤처럼 기존 카드들 사이나 왼쪽에 카드를 넣으려면, 카드를 놓는 순간 마우스의 X 좌표를 계산해서 적절한 순서(Index)를 찾아줘야 합니다.

 

 

 

 

-깃허브연동

 

방법 A: GitHub Desktop 사용 (가장 추천)

VS Code의 기능보다 훨씬 직관적입니다.

  1. GitHub Desktop 설치.
  2. File -> Add Local Repository를 선택해 유니티 프로젝트 폴더를 선택.
  3. 깃 저장소가 아니라면 생성(Create)하라는 메시지가 뜹니다. 이때 Git Ignore 템플릿을 'Unity'로 선택하세요.
  4. Commit 후 Publish를 누르면 깃허브 웹사이트로 프로젝트 전체가 올라갑니다.

 

 

 

걍 화면을 크게하면 해결되는 문제이네 

 

 

걍 필드에 나가잇어도 마나 표시되도록 

 

 

 

 

 

 

 

  1. 오브젝트 만들기:
    • Hierarchy 창 빈 곳 우클릭 -> Create Empty 클릭 (이름: TurnManager)
    • 이 오브젝트에 방금 만든 TurnManager.cs 스크립트를 드래그해서 붙입니다.
  2. 인스펙터(Inspector) 칸 채우기:
    • Button Image: 화면에 만들어둔 EndTurnButton 오브젝트를 드래그해서 이 칸에 넣습니다.
    • Yellow Sprite: 프로젝트 창(Sprites 폴더)에 있는 노란색 버튼 이미지를 드래그해서 넣습니다.
    • White Sprite: 프로젝트 창에 있는 하얀색(또는 갈색) 버튼 이미지를 드래그해서 넣습니다. (이 칸을 비워두면 안 됩니다!)
  3. 클릭 이벤트 연결하기:
    • Hierarchy 창에서 EndTurnButton 오브젝트를 클릭합니다.
    • 오른쪽 Inspector 창을 내려서 On Click () 항목을 찾습니다.
    • + 버튼을 누릅니다.
    • None (Object) 칸에 아까 만든 TurnManager 오브젝트(스크립트 붙인 것)를 드래그해서 넣습니다.
    • 오른쪽 드롭다운 메뉴(No Function)를 눌러 **TurnManager > ToggleTurnButton**을 선택합니다.

 

 

 

 

 

1. 이론적 배경 (왜 문제가 발생했고, 어떻게 해결했나)

문제의 원인: Sibling Index의 이중 역할

유니티 UI에서 하이어라키(Hierarchy)의 순서인 Sibling Index는 두 가지 역할을 동시에 수행합니다.

  1. 배치 순서: Horizontal Layout Group 안에서 카드가 왼쪽에서 몇 번째에 있을지 결정합니다.
  2. 출력 순서: 화면에 누가 더 앞에 보일지 결정합니다. (목록 아래쪽일수록 나중에 그려져서 앞면 노출)
  • 과거: 카드를 크게 보여주기 위해 SetAsLastSibling()을 써서 출력 순서를 맨 앞으로 보냈습니다. 하지만 이로 인해 배치 순서까지 맨 오른쪽으로 강제 이동되면서 카드가 순간이동하고 배치가 섞인 것입니다.

해결 방법: 출력 순서의 분리 (Canvas Override)

카드의 배치 순서(Sibling Index)는 건드리지 않고, 출력 우선순위만 따로 떼어내서 높여주는 것입니다. 이를 위해 개별 캔버스(Nested Canvas)를 사용합니다.


2. 코드 변화 (정확히 바뀐 줄)

[호버 시 앞면 노출 로직]

  • 과거 코드 (버그 발생):
  •     this.transform.SetAsLastSibling(); 
    // 결과: 하이어라키 순서가 바뀌어 배치가 섞임
      
  • 현재 코드 (해결):
        canvas.overrideSorting = true;
    canvas.sortingOrder = 100;
    // 결과: 하이어라키 순서(배치)는 그대로인데, GPU가 이 카드만 가장 나중에(맨 앞에) 그림
      

[드래그 중 하수인 비켜나기 로직]

  • 과거 방식: 카드를 잡고 있으면 필드에는 아무 변화가 없고, 놓는 순간 자리를 찾아 들어갔습니다.
  • 현재 방식 (Placeholder 도입):
    • 원리: 실제 카드는 마우스를 따라다니도록 부모를 이탈시키고, 대신 필드에 **너비 데이터만 가진 투명한 가짜 물체(LayoutElement)**를 넣습니다. Horizontal Layout Group은 이 가짜 물체를 카드라고 인식하고 공간을 벌려줍니다.
          placeholder = new GameObject("Placeholder");
      LayoutElement le = placeholder.AddComponent<LayoutElement>();
      le.preferredWidth = cardRT.rect.width; // 카드와 똑같은 가로 너비를 할당
        

[하단 잘림 방지 로직]

  • 과거 방식: 피벗이 중앙(0.5, 0.5)이라 배율을 키우면 아래쪽으로도 커져서 화면 밖으로 나갔습니다.
  • 현재 방식:
    • 에디터에서 Pivot Y를 0으로 설정.
    • 이론적으로 **크기 계산의 기준점(Origin)**이 카드의 바닥 선이 됩니다. 따라서 Scale을 1.5배 키우면 바닥은 고정된 채 위쪽과 옆으로만 확장되어 아래쪽이 잘리지 않습니다.