ଘ(੭ 목차 )੭
1️⃣ 꿀팁
ੈ ✩ Git 커밋 태그
ੈ ✩ Rider 단축키
2️⃣ 코드 공부
3️⃣ 트러블 슈팅
ੈ ✩ 문. 시. 해. 알.
① 싱글톤 Instance 오류
② PlayerCondition.cs 배고픔 감소 오류
4️⃣ 추가로 알게된 점
5️⃣ 복습
6️⃣ 레벨업 세션
1️⃣ 꿀팁
ੈ ✩ Git 커밋 태그 (Conventional Commits)
| feat | 기능 추가 | feat: Add enemy chase system |
| fix | 버그 수정 | fix: Resolve null reference on player |
| refactor | 리팩토링 (동작 안 바꾸고 코드만 개선) | refactor: Clean up score logic |
| style | 코드 포맷, 세미콜론, 들여쓰기 | style: Apply consistent spacing |
| docs | 문서 작업 (README 등) | docs: Update project intro |
| test | 테스트 코드 추가 | test: Add enemy AI test case |
| chore | 기타 변경 (빌드 설정, 패키지 업데이트 등) | chore: Update Unity version |
| perf | 성능 개선 | perf: Optimize draw calls |
| ci | CI 설정 변경 | ci: Fix GitHub Actions workflow |
| build | 빌드 관련 수정 | build: Change build target to Android |
| asset | 🎨 에셋 추가/수정 (씬, 사운드, 이미지 등) | asset: Add mountain background and river prefab |
ੈ ✩ Rider 단축키
- command option L -> 줄 정리
- command D -> 아래로 복붙
- command 누르고 클릭 -> 자동 이동 ~ ଘ
ੈ ✩ 그 외 자주 쓰는 Rider 단축키 (Mac)
| 자동 완성 | ⌃ + Space | 코드 자동 완성 (Ctrl + Space) |
| 이름 변경 (변수, 메서드 등) | Shift + F6 | 리팩토링 이름 변경 |
| 전체 탐색 (파일, 클래스 등) | Double Shift | 모든 항목 검색 |
| 메서드 간 빠르게 이동 | ⌘ + F12 | 현재 파일 내 심볼 구조 보기 |
| 최근 수정한 코드로 이동 | ⌘ + Shift + Backspace | 마지막 편집 위치로 점프 |
2️⃣ 코드 공부
ੈ ✩ 영어 문장 쓰듯이 코드로 바꿔보기
| "플레이어가 앞으로 간다" | player.Move(forward); |
| "적이 나를 쏜다" | enemy.Shoot(player); |
| "점수가 100보다 크면 승리" | if(score > 100) Win(); |
ੈ ✩ 연습 방법
- 코드 짤 때 "영어 문장처럼 말로 먼저 말해보고 → 코드로 바꾸기" 연습해 보자
- 누가 → 뭘 → 어떻게를 기준



"고양이가 플레이어를 따라온다"
public class Cat
{
public void Follow(Player player)
{
Debug.Log("Cat follows player joyfully.");
}
}
3️⃣ 트러블 슈팅
‧₊˚ 싱글톤 Instance 오류 ‧₊˚
ੈ ✩ 문제 (Problem)
Player.cs에서 CharacterManager.Instance.Player = this;를 호출하려 했으나,
Instance가 정의되지 않았다는 컴파일 오류 발생
ੈ ✩ 시도한 점 (What was tried)
- CharacterManager 클래스 내부를 확인
- public static CharacterManager InstanceManager 라는 속성이 정의되어 있었고
- Instance라는 이름은 없음 → 네이밍 불일치 확인
ੈ ✩ 해결 (Solution)
- CharacterManager.cs 내부의 싱글톤 속성 이름을

➤

수정하여 Player.cs에서 접근 가능한 형태로 통일
ੈ ✩ 알게 된 점 (What was learned)
- 싱글톤 패턴의 Instance 명칭은 반드시 통일되어야 외부에서 사용할 수 있음
- 이름 하나 다르게 썼다고 코드 전체가 작동하지 않음 → 네이밍 규칙 매우 중요!
‧₊˚ PlayerCondition.cs 배고픔 감소 오류 ‧₊˚
ੈ ✩ 문제 (Problem)
배고픔 (hunger)이 줄지 않아 체력 (helath) 도 줄지 않음 !!
ੈ ✩ 시도한 점 (What was tried)
- Subtract() 메서드와 noHungerHealthDecay 값 확인
- hunger.curValue <= 0f 조건 사용
ੈ ✩ 해결 (Solution)

- hunger, health 모두 == 0f → <= 0f로 변경
(float 값은 정확히 0이 되기 어려워 == 비교는 실패함) - 결과적으로 체력도 정상적으로 감소했고 Die()가 호출됨
ੈ ✩ 알게 된 점 (What was learned)
- float 비교는 <=, >= 같은 안전한 비교 방식 사용해야 함 !
- ==로 비교하면 아주 작은 소수점 오차 때문에 조건문이 통과되지 않음
4️⃣ new realization
- Awake() 내부의 싱글톤 초기화 조건은 반드시 null 체크 → 할당 → 중복 제거 순으로 작성해야 함
- new GameObject().AddComponent<T>() 방식의 싱글톤은 씬에 오브젝트가 없을 때 예외적 생성 방식임
ੈ ✩ 1. 방어 코드 (Defensive Code)
예상치 못한 상황에서도 프로그램이 멈추지 않고 정상 작동하도록 막아주는 코드
‧₊˚ 예시 1: 오브젝트가 없을 수도 있음
적이 죽어서 enemy가 없어졌는데도 TakeDamage()를 호출하면 에러!
null 검사로 방어(예외 예방)
‧₊˚ 예시 2: UI 버튼 연결 안 돼 있을 때
‧₊˚ 비유:
“문이 열려 있을 수도, 잠겨 있을 수도 있다”
→ 무작정 열지 말고, 먼저 문이 있는지 확인하고 여는 것
ੈ ✩ 2. Fallback 코드
다운타임 방지 코드
- 하이러키에 오브젝트가 없어도 강제로 만들어서 진행되게 하는 코드
- 프로그램 멈추지 않게 대체 경로를 마련하는 예외적 대처 코드
ੈ ✩ 3. 싱글톤(Singleton)
‧₊˚ 의미
프로젝트 전체에서 단 하나만 존재하는 객체를 만들고, 어디서든 접근 가능하게 하는 디자인 패턴
예: GameManager, UIManager, AudioManager
➡ 나중에 어디서든 GameManager.Instance로 접근 가능!
‧₊˚ 비유
학교에 딱 한 분 계신 교장선생님
누구나 “교장선생님.Instance”로 부를 수 있다.
2명 이상 존재하면 안 되니까 조건문으로 방어
ੈ ✩ 4. new GameObject().AddComponent<T>() 싱글톤 예외 생성
‧₊˚ 의미
- 씬에 MyManager 오브젝트가 없을 수도 있음
- 그러면 코드가 에러 나니까 → 강제로 새 게임오브젝트 만들고, 컴포넌트 붙임!
‧₊˚ 비유
“교장선생님이 학교에 안 왔으면 → 새로 불러와서 자리 앉히는 것”
➡ 게임에 꼭 필요한 매니저가 빠져 있어도 게임이 안 멈추고 진행되게 만드는 방어 코드
5️⃣ 복습
ੈ ✩용어 정리
| 클래스 | Cat, Player | 설계도, 타입 |
| 객체 | cat, player | 내용물 (인스턴스) |
| 메서드 | Follow() | 행동, 동작 |
| 매개변수 | (Player player) | 메서드에게 전달되는 값 |
| 생성 | new Cat() | 설계도로 실제 물건 만들기 |
ੈ ✩ 1. class = 설계도
- 클래스는 보통 PascalCase (= 단어 첫 글자 모두 대문자)
- 설계도니까 눈에 띄게 대문자로 쓰는 게 규칙
public class Player { ... }
public class Cat { ... }
ੈ ✩ 2. 객체, 변수
- 변수, 매개변수는 camelCase (= 첫 글자 소문자)
Player player = new Player();
Cat myCat = new Cat();
‧₊˚ 예시
public PlayerController controller;
- PlayerController는 클래스(설계도)
- controller는 이 설계도로 만든 변수
PlayerController 클래스 타입의 controller라는 객체 변수를 선언함
ੈ ✩ 3. new Cat() → class로 객체 생성
- new -> class를 바탕으로 객체를 만드는 키워드
Cat cat = new Cat(); // Cat class로 cat이라는 고양이 한 마리 생성
ੈ ✩ 4. Method
- 메서드 이름도 보통 PascalCase로 씀 (대문자 시작)
public void Follow(Player player) { ... }
public void Eat() { ... }
ੈ ✩ 5. 매개변수
- 함수 괄호 안에 들어가는 값이 매개변수
public void Follow(Player player) { ... }
| Player | 매개변수 타입 (클래스) |
| player | 매개변수 이름 (소문자 변수) |
- 메서드는 "명확한 동작을 나타내는 "명사형 동사" 이기 때문에
→ Jump(), TakeDamage()처럼 PascalCase(대문자)로 작성
‧₊˚ Usage Timing
다른 객체의 정보를 함수 안으로 가져와야 할 때
“고양이가 플레이어를 따라가게 하려면 → 플레이어의 위치를 알아야 함”
ੈ ✩ 6. 모든 변수는 소문자인가? -> 상수(Constant) 제외하고!
| 클래스 | 대문자 시작 | Player, Cat |
| 변수/객체 | 소문자 시작 | player, cat, score |
| 매개변수 | 소문자 시작 | player, damage |
| 함수/메서드 | 대문자 시작 | Follow(), TakeDamage() |
일반적으로는
- 클래스/메서드 → PascalCase (대문자 시작)
- 변수/매개변수 → camelCase (소문자 시작)
- 상수(Constant)는 예외적으로 대문자 + 언더바
‧₊˚ 예시
‧₊˚ 요약
| 클래스 | 설계도 = 대문자 |
| 객체/변수 | 소문자로 시작 |
| new Cat() | 클래스로 객체 만들기 |
| Follow() | 동작(함수) = 대문자 |
| player | 매개변수(소문자 변수) |
| 모든 변수는 소문자? | 일반적으로 맞음 |
(공사 중..)
ੈ ✩ 메서드와 함수
| 함수(function) | 단독으로 존재 가능함 (C언어 같은 데서) |
| 메서드(method) | 클래스 안에 들어 있는 함수 -> C#은 다 method임! |
C#에서는 모든 함수가 클래스 안에 있어야 하므로 → 전부 "메서드"라고 부름.
‧₊˚ 예시
public void Jump() { ... }
ੈ ✩ 예제
플레이어가 적을 공격하면 적 체력이 줄어든다.

| Player | 플레이어 클래스 (공격 주체) |
| Enemy | 적 클래스 (체력 보유) |
| Attack() | 플레이어가 적을 공격하는 method |
| TakeDamage() | 적이 데미지를 받는 method |
| enemy | 매개변수: 공격당하는 대상 |
| amount | 매개변수: 데미지 양 |
ੈ ✩ GetComponent
현재 오브젝트에 붙어 있는 컴포넌트를 코드에서 가져오고 싶을 때
→ 이 스크립트가 붙어 있는 오브젝트에서 Rigidbody를 찾아서 가져옴.
📚 예:
"이 게임오브젝트에 리지드바디 붙어 있으면 가져와서 쓸게~"
✅ | 와 || 차이
| ` | ` | OR (Bitwise) |
| ` | ` |
실전에서 조건문에 쓰는 건 ||
✅ 싱글톤(Singleton) 초등학생도 이해하게
📚 비유:
게임에 딱 하나만 존재하는 사령탑
예: 게임 매니저는 하나만 있어야 함 (중복되면 망함)
🔧 싱글톤 코드 예시
쓰는 법:
| 클래스 | Player, Enemy | 설계도 (대문자 시작) |
| 변수 | player, enemy | 실제 객체 이름 (소문자 시작) |
| 메서드 | Jump(), Attack() | 동작. 클래스 안에서만 사용 (대문자 시작) |
| 매개변수 | (Enemy enemy) | 메서드가 받는 값 (소문자 시작) |
| new Cat() | Cat 설계도로 새 객체 만듦 | |
| GetComponent<T>() | 오브젝트에 붙은 컴포넌트 가져오기 | |
| ` | ` | |
| 싱글톤 | GameManager.Instance | 프로그램에 딱 하나만 존재하게 |
6️⃣ 레벨업 세션
1. 고정형 데이터 vs 변동형 데이터
| 고정형 데이터 (Static Data) | 불변의 기준 데이터를 의미. 매번 새로 생성할 필요 없이 공유됨. | 아이템 이름, 등급, 설명 등 |
| 변동형 데이터 (Dynamic Data) | 게임 도중 변경되며 유저별로 다른 데이터를 의미. | 현재 내구도, 강화 수치, 소유 여부 등 |
→ 고정형 정보는 기준 테이블로 따로 저장하고, 변동형 정보는 인스턴스 단위로 관리하는 것이 핵심!
2. JSON 직렬화 & 기획 테이블 관리
🔹 직렬화(Serialization)란?
- 객체를 저장 가능한 포맷(JSON, Binary 등)으로 변환하는 과정
- 단순 저장/로드가 아니라 데이터의 구조화가 핵심!
- 게임에서는 주로 설정 파일 저장, 서버와의 통신, 데이터 테이블 로딩 등에 사용됨
기획 테이블 → JSON 구조화 방식
작업 흐름
- Excel에서 기획 데이터 작성
- 변수명 / 자료구조 / 설명 반드시 포함
- ExcelDataSample.xlsx 같은 형식 사용
- 필드 예시: key, name, grade, durability, availableOptions, description
- ExcelToJsonWizard 사용 (x64.zip 설치 필요)
- 반드시 Excel 종료 후 실행!
- .json 파일 자동 생성됨
- enum 필드도 대응 가능
- Unity에서 ScriptableObject로 불러오기
- JSON → ScriptableObject or DataContainer 형태로 역직렬화하여 사용
- 데이터 접근 방식
- GetByKey() or GetByIndex() 사용
- 멀티 시트는 지양 (관리 복잡도 증가)
구조 설계 팁
🔹 불변 데이터 + 변동 데이터 분리 예시
→ ItemInfo는 그대로 두고, 유저별 상태는 ItemInstance에서 관리!
🔹 옵션 구조
→ Option을 별도로 관리하면 유지보수 & 밸런싱이 매우 편해짐!
🧭 Rider 기준 단축키 정리
| 코드 참조 찾기 | ⌘ + B or ⌘ + Click | 정의/참조로 이동 |
| 심볼 검색 | ⇧ + ⌘ + O | 클래스, 함수 등 빠른 검색 |
| 파일 검색 | ⌘ + ⇧ + F | 전체 파일 내용 검색 |
| 빠른 수정 | ⌘ + ⏎ | 자동완성 및 리팩토링 |
| 변수 이름 변경 | ⇧ + F6 | 리팩토링 - 이름 변경 |
| 디버그 실행 | ⌃ + D | 브레이크포인트 따라가며 실행 |
| 한 줄 삭제 | ⌘ + X or ⌘ + Delete | 현재 줄 삭제 |
| 줄 이동 | ⌘ + G | 원하는 줄로 이동 |
| 직접 실행창 | ⌥ + F12 | Evaluate Expression |
| 솔루션 탐색기 | ⌘ + ; | 파일, 구조 등 탐색 |
| 코드 블럭 정리 | ⌘ + ⌥ + L | 자동 정렬 & 들여쓰기 |
🧪 디버깅 팁 (꼭 기억하기!)
- Debug.Log()만 쓰지 말고 중단점(Breakpoint) 적극 활용
- Rider에서 디버깅 시 Evaluate Expression 창 활용 가능
- **호출 스택(Call Stack)**을 반드시 확인
- NullReferenceException이 발생하면:
- . (점) 앞을 보자!
- 그 값이 null임 → 곧바로 원인 파악 가능