no image
내일배움캠프 72일차 TIL [최종 프로젝트 Black Chamber]
🗓️ 오늘 하루 일정✅ 오전10:00 ~ 10:30 : 팀 회의(배포 테스트/분석 목표 확정)10:30 ~ 11:30 : 이벤트 스키마 확정(player_death, stage_complete, stage_failed, mode_switch + 파라미터 정의)11:30 ~ 12:30 : UGS 연결/대시보드 점검(패키지/프로젝트 연동 확인)🍽️ 점심시간13:00 ~ 14:00 : 점심✅ 오후14:00 ~ 15:00 : GA.cs 래퍼 구현(RecordEvent), 공통 파라미터/스냅 처리15:00 ~ 16:00 : 초기화/업로드 파이프라인(UGSInitializer, AnalyticsAutoFlusher with UNITY_EDITOR Flush)16:00 ~ 17:00 : 게임 로직 연동StageR..
2025.10.16
no image
내일배움캠프 71일차 TIL [최종 프로젝트 Black Chamber]
🗓️ 오늘 하루 일정✅ 오전10:00 ~ 13:00 : 오전회의 & QA🍽️ 점심시간13:00 ~ 14:00 : 점심시간✅ 오후레이어 조정 / CCTV 사운드 추가 / 버그 수정 (오후 전체)🍽️ 저녁시간18:00 ~ 19:00 : 저녁시간✅ 저녁19:00 ~ 20:00 : 강의 수강20:00 ~ 21:00 : 팀 회의(진행 상황 공유, 내일 작업 정리)✅ 오늘 학습 키워드Physics LayerMask vs Sorting Order(정렬 순서)Fog of War: Obstacle/Door 레이어 분리, 트리거 무시 동작CCTV SFX: PlayOneShot 사용, 중복 재생(Debounce) 처리, 오디오 믹서 라우팅레이어 변경 시 점검 체크리스트(레이어마스크, 충돌 매트릭스, 프리팹 적용)✅ 오..
2025.10.15
no image
내일배움캠프 70일차 TIL [최종 프로젝트 Black Chamber]
🗓️ 오늘 하루 일정✅ 오전10:00 ~ 10:40 : GunData 구조 정리 — Max/Cur 분리, OnValidate() 클램프 규칙 확정10:40 ~ 11:30 : Shooter.Initialize 수정 — Cur로 시작값 세팅, Max로만 클램프, 하드코딩 상한 제거11:30 ~ 12:30 : WeaponManager 점검 — 동일 인덱스 전환 가드, 페이즈 전환 시 재진입 방지🍽️ 점심시간13:00 ~ 14:00 : 점심✅ 오후13:30 ~ 15:00 : UIHUDSlots ↔ Weapon 전환 StackOverflow 루프 원인 추적 및 가드 추가15:00 ~ 16:30 : 입력 이슈 핫픽스 — WorldSpace HUD 무시, Selectable/레이어 기반 UI 차단 필터 적용16:..
2025.10.14
no image
내일배움캠프 69일차 TIL [최종 프로젝트 Black Chamber]
🗓️ 오늘 하루 일정✅ 오전10:00 ~ 11:00 : 팀 회의(역할 분담, 금일 목표 확정)11:00 ~ 12:30 : Fog of War 초기화 에러 재현 및 원인 파악(Scan Spacing Per Unit)🍽️ 점심시간13:00 ~ 14:00 : 점심시간✅ 오후14:00 ~ 16:30 : FogPlane 범위/위치 점검(그리드 X·Y, Mid Point, Unit Scale) 및 머티리얼 교체(Unlit)16:30 ~ 18:00 : 문 레이어( Door ) 오클루전 확인, 리빌 옵션/알파 튜닝, 전체 맵 테스트🍽️ 저녁시간18:00 ~ 19:00 : 저녁시간✅ 저녁19:00 ~ 20:30 : 씬 최종 점검, 설정값 가이드 정리 및 TIL 작성✅ 오늘 학습 키워드Fog of War(2D XY ..
2025.10.13
no image
내일배움캠프 68일차 TIL [최종 프로젝트 Black Chamber]
🗓️ 오늘 하루 일정✅ 오전09:00 ~ 13:00 : 발표 준비🍽️ 점심시간13:00 ~ 14:00 : 점심시간✅ 오후14:00 ~ 15:00 : 최종발표 전 중간발표15:00 ~ 16:00 : 휴식16:00 ~ 18:00 : 팀 회의 — 추석 연휴 개발/기획 범위 논의🍽️ 저녁시간18:00 ~ 19:00 : 저녁시간✅ 오늘 학습 키워드https://youtu.be/VFJO8QlCwDA 중간발표✅ 오늘 학습 한 내용을 나만의 언어로 정리하기발표는 문제–접근–결과–교훈의 4단 구조로 정리하면 이해가 빠르다. 데모는 타임라인에 맞춰 입력 시퀀스를 스크립트화해야 실수가 줄어든다.연휴 스프린트는 “핵심 루프 1분 데모”를 최우선으로 두고 나머지는 Nice-to-have로 분리한다.🧩 학습하며 겪었던 문..
2025.10.02
no image
내일배움캠프 67일차 TIL [최종 프로젝트 Black Chamber]
🗓️ 오늘 하루 일정✅ 오전09:00 ~ 12:00 : 인터랙션 정리(아이템: 돈/탄창 IInteractable 적용), UI 수정(F키 흰색), UIBase 두트윈 기본 비활성(로딩/게임오버/클리어/NPC)🍽️ 점심시간13:00 ~ 14:00 : 점심시간✅ 오후14:00 ~ 16:00 : 직렬화 충돌(triple canvasGroup) 원인 파악 및 수정, SceneInitializer 기반 UIKey 동기화 점검16:00 ~ 18:00 : 팀 PPT 제작(진행 현황, 기술적 의사결정 카드 정리)🍽️ 저녁시간18:00 ~ 19:00 : 저녁시간✅ 저녁19:00 ~ 21:00 : 저녁 스크럼(내일 목표 확정, 리스크 공유)영상 다시 촬영 (원테이크) (설명은 내일)발표 리허설PPT 옮기기파일제출. ..
2025.10.01
no image
내일배움캠프 66일차 TIL [최종 프로젝트 Black Chamber]
🗓️ 오늘 하루 일정✅ 오전09:00 ~ 10:30 : UIBase에 DOTween 프리셋(오픈/클로즈+유틸) 설계 정리10:30 ~ 12:00 : 로딩 화면 구조 재설계(전용 카메라/레이어 분리 초안)🍽️ 점심시간13:00 ~ 14:00 : 점심시간✅ 오후14:00 ~ 16:30 : LoadingCanvas 구현 보강(활성 보장, 최소 2초 노출) · UIRoot.HideAllSceneUIs() 추가16:30 ~ 18:00 : 로딩 전용 카메라 세팅(SS-Camera, CullingMask) 및 씬 전환 흐름 점검🍽️ 저녁시간18:00 ~ 19:00 : 저녁시간✅ 저녁19:00 ~ 20:30 : Dimmer 색감/알파 수정, 팝업들에 DOTween 적용20:30 ~ 21:00 : QA 피드백 반영..
2025.09.30
no image
내일배움캠프 65일차 TIL [최종 프로젝트 Black Chamber]
🗓️ 오늘 하루 일정✅ 오전10:00 ~ 11:00 : 최종 프로젝트 발제 진행11:00 ~ 12:00 : UI 버그 및 타이틀 사운드 버그 수정🍽️ 점심시간13:00 ~ 14:00 : 점심✅ 오후14:00 ~ 16:00 : NPC 대사 컨텍스트 설계(FirstMeet/Fail/Clear 등) 초안 → 보류/원복 결정16:00 ~ 18:00 : 씬 전환 로딩 흐름 검토SceneLoader/SceneInitializer로 2초 노출 후 전환 시나리오 작성최종적으로 로딩 씬 대신 “UI 오버레이” 방식으로 전환 결정✅ 저녁19:00 ~ 21:00 : 로딩 UI 연출 기획Shift 애니메이션 이벤트(AE_RunOn/AE_RunOff)로 Run 토글 + 스태미나 바 증감 데모 설계DOTween 트랜지션(암살..
2025.09.29
반응형

🗓️ 오늘 하루 일정

✅ 오전

  • 10:00 ~ 10:30 : 팀 회의(배포 테스트/분석 목표 확정)
  • 10:30 ~ 11:30 : 이벤트 스키마 확정
  • (player_death, stage_complete, stage_failed, mode_switch + 파라미터 정의)
  • 11:30 ~ 12:30 : UGS 연결/대시보드 점검(패키지/프로젝트 연동 확인)

🍽️ 점심시간

  • 13:00 ~ 14:00 : 점심

✅ 오후

  • 14:00 ~ 15:00 : GA.cs 래퍼 구현(RecordEvent), 공통 파라미터/스냅 처리
  • 15:00 ~ 16:00 : 초기화/업로드 파이프라인
  • (UGSInitializer, AnalyticsAutoFlusher with UNITY_EDITOR Flush)
  • 16:00 ~ 17:00 : 게임 로직 연동StageRunTracker, ModeSwitchTracker 구독)
  • (PlayerHealthEventHandler·PlayerDeathHook, Bullet/Shooter.ReportAttacker,
  • 17:00 ~ 18:00 : 트러블슈팅
    • Event Browser 미표시(환경 불일치 → production 전환)
    • Invalid(정의 안 된 build_version) → 코드 제거 후 재전송

🍽️ 저녁시간

  • 18:00 ~ 19:00 : 저녁

✅ 저녁

  • 19:00 ~ 20:00 : 로비에서 실패 찍힘 이슈 해결
  • (트래커 게임씬 전용 배치/가드, PlayerDeathHook에서 트래커 없으면 실패 스킵)
  • 20:00 ~ 21:00 : 이중 구독으로 인한 중복 전송 수정(인스펙터/코드 중 하나만 유지) 및 최종 검증

✅ 오늘 학습 키워드

UGS Analytics, Custom Event 스키마, Event Browser(Valid/Invalid), dev/prod 환경, RecordEvent(new CustomEvent), Flush 타이밍(WebGL/Editor), StageRunTracker, ModeSwitchTracker, Health 이벤트 구독, ReportAttacker(killer_id), Invalid 원인 분석(additional property), DDOL/씬 가드.


✅ 오늘 학습 한 내용을 나만의 언어로 정리하기

  • UGS Analytics 흐름: 초기화(UnityServices.InitializeAsync → StartDataCollection) 후, 게임 로직에서 한 지점당 한 번 커스텀 이벤트를 RecordEvent(new CustomEvent(...))로 전송한다. WebGL/에디터는 중요한 순간에 Flush()를 호출하면 확인이 빨라진다.
  • 스키마 우선: 이벤트/파라미터는 Event Manager에 먼저 정의·Publish하고, 코드가 그 이름/타입을 정확히 일치시켜야 한다. 하나라도 다르면 Invalid로 버려진다.
  • 설계 포인트:
    • player_death는 좌표(0.5 격자), killer_id, gameplay_mode가 핵심.
    • stage_complete/failed는 attempt/시간/킬수를 한 번만.
    • mode_switch는 전환 좌표 + 잠입 지속시간.
  • 씬 생명주기: 애널리틱스용 컴포넌트는 게임씬 전용으로 두고, DDOL 오브젝트에는 초기화/플러셔만 둔다. 그렇지 않으면 로비/타이틀에서도 이벤트가 새어 나간다.

🧩 학습하며 겪었던 문제점 & 에러

1) Event Browser에 커스텀 이벤트가 안 보임

  • 정의: 에디터에서 보냈는데 Event Browser에 player_death 등이 없음.
  • 시도: smoke 이벤트 전송, Flush 주기 늘림.
  • 해결: 환경 불일치(대시보드 production vs 코드 development) → production으로 통일.
  • 배운 점: UGS는 환경 분리가 철저. 콘솔 로그로 UGS Initialized (env)를 항상 확인.
  • 다시 만나면: 초기화 직후 환경/플러시 체크리스트부터 확인.

2) Invalid: Additional property 'build_version'

  • 정의: Event Manager에 없는 파라미터를 코드에서 전송.
  • 시도: 파라미터 추가/Publish vs 코드 제거 비교.
  • 해결: 코드에서 전송 제거(가장 빠름).
  • 배운 점: “스키마 ≠ 코드”면 데이터는 버려진다.
  • 다시 만나면: Invalid 탭 Reason 확인 → 스키마/코드 중 하나를 즉시 정렬.

3) 로비만 가도 stage_failed가 찍힘

  • 정의: DDOL 오브젝트에 붙은 StageRunTracker가 로비에서도 살아있음.
  • 시도: 트래커 위치 조정.
  • 해결: 트래커는 게임씬 전용 배치 + 비게임씬 가드(IsGameplayScene) + PlayerDeathHook에서 트래커 없으면 실패 스킵.
  • 배운 점: 분석 로직은 씬 가드가 필수.
  • 다시 만나면: DDOL에는 초기화만, 나머지는 씬별.

4) player_death 중복 전송

  • 정의: OnPlayerDamaged/OnPlayerDie가 2번씩 호출.
  • 시도: 로그로 호출 경로 추적.
  • 해결: Health 이벤트 이중 구독(인스펙터 + 코드) → 한 방식만 남김(자동 구독 유지).
  • 배운 점: UnityEvent는 AddListener 중복에 주의.
  • 다시 만나면: _wired 플래그로 방지 또는 에디터 연결 제거.

5) player_death가 가끔 안 찍힘

  • 정의: 사망 로그는 찍히는데 이벤트 미수신.
  • 시도: 전송 직전 로그/널가드 추가.
  • 해결: killer_id 기본값을 "unknown"으로 보정, OnDie()에서 SENT 로그와 Flush()로 확인.
  • 배운 점: 보내는 값이 비어도 Invalid로 버려질 수 있음.
  • 다시 만나면: 전송 레벨 로그(GA.Send …)를 항상 켜서 추적.

📝 메모

  • Data Explorer 리포트 저장:
    1. player_death 히트맵용 CSV (stage_id, killer_id, x, y)
    2. 완료/실패 비교표(완료율, 평균 플레이타임, 평균 킬수)
    3. mode_switch 빈도·지점
  • killer_id 네이밍 고정: guard_melee, guard_rifle, cctv_turret, trap_spike, mine 등 일관 키 사용.
  • StageRunTracker는 게임씬에 하나만. 중복 생성/구독 주의.
  • WebGL 배포 전: Ad-block off 가이드, 중요한 지점 Flush() 재확인.

반응형
반응형

🗓️ 오늘 하루 일정

✅ 오전

  • 10:00 ~ 13:00 : 오전회의 & QA

🍽️ 점심시간

  • 13:00 ~ 14:00 : 점심시간

✅ 오후

  • 레이어 조정 / CCTV 사운드 추가 / 버그 수정 (오후 전체)

🍽️ 저녁시간

  • 18:00 ~ 19:00 : 저녁시간

✅ 저녁

  • 19:00 ~ 20:00 : 강의 수강
  • 20:00 ~ 21:00 : 팀 회의(진행 상황 공유, 내일 작업 정리)

✅ 오늘 학습 키워드

  • Physics LayerMask vs Sorting Order(정렬 순서)
  • Fog of War: Obstacle/Door 레이어 분리, 트리거 무시 동작
  • CCTV SFX: PlayOneShot 사용, 중복 재생(Debounce) 처리, 오디오 믹서 라우팅
  • 레이어 변경 시 점검 체크리스트(레이어마스크, 충돌 매트릭스, 프리팹 적용)

✅ 오늘 학습 한 내용을 나만의 언어로 정리하기

  • FogWar는 “물리 레이어”만 본다. 정렬 순서가 아무리 맞아도 LayerMask에 포함되지 않으면 스캔/가림이 동작하지 않는다. Obstacle과 Door를 분리하고, 트리거 무시 옵션을 이해하면 재현/수정이 빨라진다.
  • 정렬(Sorting)과 레이어는 서로 다른 축이다. 화면에 무엇이 위에 보일지(정렬)와 충돌/시야 판정에 들어갈지(물리 레이어)는 독립적으로 관리해야 한다.
  • CCTV 사운드는 짧고 자주 난다. PlayOneShot + 간단한 쿨다운(또는 풀링)으로 중첩 재생과 클리핑을 방지하고, Mixer의 SFX 그룹으로 볼륨/필터를 일괄 제어한다.

🧩 학습하며 겪었던 문제점 & 에러

1) FogWar가 레이어 바꾸자마자 “안 되는 것처럼” 보임

  • 문제정의: 벽/문 레이어를 손봤더니 시야 차단이 일부 구간에서 사라짐.
  • 시도: 정렬 순서와 Z값을 조정했으나 변화 없음.
  • 해결 방법: FogWar에서 쓰는 **LayerMask(Obstacle/Door)**에 새 레이어가 빠져 있었음. 인스펙터에서 해당 레이어 체크 후 스캔 재실행. 트리거 콜라이더는 무시되는 경로라 필요 시 non-trigger로 교체.
  • 새롭게 알게 된 점: FogWar는 Sorting Layer/Order를 보지 않는다. 반드시 Physics LayerMask 포함 여부부터 확인.
  • 다시 만나게 된다면: 레이어 변경 시 아래 체크리스트를 먼저 확인.
  • // 점검 스니펫: 현재 오브젝트 레이어가 마스크에 포함되는지 bool IsInMask(int layer, LayerMask mask) => (mask.value & (1 << layer)) != 0;

2) CCTV 사운드가 과하게 겹쳐 들림

  • 문제정의: 짧은 구간에서 감지 이벤트가 연속 발생하며 소리가 중첩되어 거슬림.
  • 시도: AudioSource.Play() 반복 호출 → 볼륨 피크/클리핑 발생.
  • 해결 방법: PlayOneShot(clip)로 변경하고 디바운스(쿨다운) 적용. Mixer의 SFX 그룹으로 라우팅해 전체 레벨을 통제.
  • 새롭게 알게 된 점: 다빈도 효과음은 PlayOneShot + 쿨다운이 가장 간단하고 안전.
  • 다시 만나게 된다면: 트래픽이 더 많아지면 오디오 소스 풀로 확장.
  • public class CctvBeep : MonoBehaviour { public AudioSource source; public AudioClip clip; public float cooldown = 0.25f; float _last; public void OnDetect() { if (Time.time - _last < cooldown) return; source.PlayOneShot(clip); _last = Time.time; } }

3) “레이어 높이만 바꿨는데” 총알/머리 가림 순서가 어긋나는 현상

  • 문제정의: 머리만 보이는 탑다운에서 총알이 머리 뒤로 숨는 구간 발생.
  • 시도: 총알 Z값/정렬 순서 임시 조정.
  • 해결 방법: 정렬 순서 테이블을 재확인하고 총알(Order)을 캐릭터 상단보다 한 단계 위로 고정. (예: 캐릭터 상단 -40, 총알 -39 → 필요 시 -38로 승급)
  • 새롭게 알게 된 점: 시야 판정 레이어와 화면표시 정렬은 분리해서 관리해야 안정적이다.
  • 다시 만나게 된다면: “정렬표(바닥·벽·문·캐릭터 하/상·총알·아이템)”를 위키로 고정하고, 프리팹 변경 시 자동 검사 스크립트를 추가.

📝 메모

오늘 레이어/사운드 정비로 기본 체력이 올라간 느낌이다. 작은 버그라도 바로잡아두면 내일 속도가 빨라진다. 내일은 FogWar 스캔 범위/스텝 재점검과 CCTV 감지 로직 최적화를 이어가자. 꾸준함이 답이다.


반응형
반응형

🗓️ 오늘 하루 일정

✅ 오전

  • 10:00 ~ 10:40 : GunData 구조 정리 — Max/Cur 분리, OnValidate() 클램프 규칙 확정
  • 10:40 ~ 11:30 : Shooter.Initialize 수정 — Cur로 시작값 세팅, Max로만 클램프, 하드코딩 상한 제거
  • 11:30 ~ 12:30 : WeaponManager 점검 — 동일 인덱스 전환 가드, 페이즈 전환 시 재진입 방지

🍽️ 점심시간

  • 13:00 ~ 14:00 : 점심

✅ 오후

  • 13:30 ~ 15:00 : UIHUDSlots ↔ Weapon 전환 StackOverflow 루프 원인 추적 및 가드 추가
  • 15:00 ~ 16:30 : 입력 이슈 핫픽스 — WorldSpace HUD 무시, Selectable/레이어 기반 UI 차단 필터 적용
  • 16:30 ~ 18:00 : 스토어 배선 정리 — StoreItemView 바인딩, StoreManager.TryBuy 연결, PurchasePopup 단일화, 8칸 슬롯 그리드 적용

🍽️ 저녁시간

  • 18:00 ~ 19:00 : 저녁

✅ 저녁

  • 19:00 ~ 19:25 : 스토어 슬롯/Owned 배지 최종 점검
  • 19:30 ~ 20:00 : 모의면접
  • 20:00 ~ 20:20 : 팀 저녁 스크럼
  • 20:20 ~ 20:40 : TIL 정리 및 내일 액션 아이템 메모

✅ 오늘 학습 키워드

  • ScriptableObject 데이터/상태 분리(Max* vs Cur*)
  • 이벤트 루프로 인한 StackOverflow 방지(가드·조기리턴)
  • UI 레이캐스트 필터링(WorldSpace HUD 무시, Selectable만 차단)
  • 스토어 슬롯 할당 패턴(동적 Instantiate vs 정적 8칸 매핑)
  • 단일 팝업 패턴(PurchasePopup 1개 공유)

✅ 오늘 학습 한 내용을 나만의 언어로 정리하기

  • 무기 데이터는 “템플릿(최대치)”와 “세션 상태(현재치)”를 명확히 분리해야 사이드이펙트가 없다. → GunData.max*는 상한, GunData.cur*는 시작/현재 값.
  • 발사·장전·스왑 등에서 Cur를 읽고 Max로만 클램프하면 일관성이 생긴다(초기화는 Cur, 검사는 Max).
  • UI는 보이되 입력은 막지 않게 하려면, 레이캐스트 결과 중 WorldSpace 캔버스/비인터랙티브 요소는 무시하고, 진짜 버튼/슬라이더(Selectable)만 차단한다.
  • 스토어는 슬롯마다 로직을 넣지 말고, StoreItemView가 데이터를 바인딩하고, PurchasePopup은 1개만 공유하는 구조가 유지보수에 유리하다.

🧩 학습하며 겪었던 문제점 & 에러

1) StackOverflowException (UIHUDSlots ↔ Weapon 전환 루프)

  • 문제&에러에 대한 정의
  • OnAmmoChanged → UI.Refresh → (직/간접) 무기 전환 → 다시 OnAmmoChanged로 재귀 루프 발생.
  • 내가 한 시도
  • 이벤트 분리, 호출 위치 변경, 디버그 로그로 호출 스택 확인.
  • 해결 방법
    • WeaponManager.CurrentWeaponIndex에 동일 인덱스 조기 리턴 가드 추가.
    • ApplyPhaseWeapon도 현재 슬롯이면 무시.
    • UI 갱신 루틴은 Ammo를 “읽기만” 하게 유지(설정 호출 금지).
  • 새롭게 알게 된 점
  • HUD가 상태를 “쓰기” 시작하면 루프가 생긴다. UI는 철저히 구독자(읽기 전용).
  • 이 문제&에러를 다시 만나게 되었다면
  • 모든 setter/전환 지점에 re-entrancy guard(동일 값 비교, isSwitching 플래그)부터 넣는다.

2) 공격이 씹힘(월드스페이스 ?/! HUD가 클릭을 먹음)

  • 문제&에러에 대한 정의
  • 적 머리 위 아이콘/텍스트가 Pointer Over UI로 판정되어 사격 입력이 차단.
  • 내가 한 시도
  • 기존 IsPointerOverUI 사용, 캔버스 설정 변경 시도.
  • 해결 방법
    • 커스텀 레이캐스트: CanvasGroup.blocksRaycasts=false·Graphic.raycastTarget=false 무시,
    • WorldSpace Canvas 무시 옵션 추가, Selectable만 차단 or 특정 레이어만 차단.
  • 새롭게 알게 된 점
  • “보이는 UI”와 “입력 차단 UI”는 다르다. 차단 기준을 명확히 하면 입력 안정성이 오른다.
  • 이 문제&에러를 다시 만나게 되었다면
  • 입력 필터를 먼저 만들고, HUD는 기본적으로 통과시키는 정책으로 설계.

3) 탄약 0으로 표시 + 칼로 강제 전환

  • 문제&에러에 대한 정의
  • 초기화 시 탄이 0으로 잡혀 HasAnyAmmo=false → 근접 전환.
  • 내가 한 시도
  • 초기화 순서 변경, 임시 값 주입.
  • 해결 방법
    • Shooter.Initialize에서 curMagazine/curReserve를 읽고,
    • maxMagazine/maxReserve로 클램프하도록 통일.
    • Ammo 변경은 Shooter.AddAmmo/Reload/ForceSetAmmo로만 허용(다른 곳에서 직접 세팅 금지).
  • 새롭게 알게 된 점
  • “시작값은 Cur, 상한은 Max” 규칙 하나로 상태 일관성이 해결된다.
  • 이 문제&에러를 다시 만나게 되었다면
  • 모든 경로에서 한 API(Shooter) 로만 탄을 바꾸게 강제.

4) 스토어 슬롯 배선 혼선(PurchasePopup가 슬롯마다 붙음)

  • 문제&에러에 대한 정의
  • 각 슬롯 버튼에 팝업 함수를 직접 연결 → 중복 팝업/흐름 꼬임.
  • 내가 한 시도
  • 슬롯 프리팹 수정, OnClick 해제.
  • 해결 방법
    • PurchasePopup 1개만 화면 루트에 배치.
    • StoreItemView.Setup(entry)가 버튼 onClick을 StoreManager.TryBuy(entry)로 통일.
    • 슬롯은 데이터 바인딩만, 구매 로직은 StoreManager에서 처리.
  • 새롭게 알게 된 점
  • 팝업/결제는 중앙집중(싱글턴/매니저), 슬롯은 순수 View가 가장 안전.
  • 이 문제&에러를 다시 만나게 되었다면
  • “동적 Instantiate or 정적 8칸 매핑” 중 무엇이든 Setup(entry) 한 점으로 수렴.

📝 메모

  • 내일 할 일
    1. 스토어 정적 8칸 매핑 버전도 지원(미리 배치된 8칸에 StoreItemView.Setup만 호출).
    2. GunData에 고유 id 필드 추가(현재 displayName 사용 중) → 보유/세이브 안정화.
    3. 무기방(Armory) UI: SetStealthByGun / SetCombatByGun 버튼 배선 및 현재 선택 표시.
    4. Ammo 픽업 시 페이즈별 무기 자동 재전환 조건 명확화(예: 현재 무기=칼 && 페이즈 무기에 탄 생김 → 전환).
  • 체크리스트
    • [ ] CurrentWeaponIndex 동일 값 가드
    • [ ] ApplyPhaseWeapon 동일 슬롯 가드
    • [ ] HUD는 읽기 전용(Ammo 세팅 금지)
    • [ ] WorldSpace HUD는 기본 통과
    • [ ] PurchasePopup 단일 인스턴스 유지

반응형
반응형

🗓️ 오늘 하루 일정

✅ 오전

  • 10:00 ~ 11:00 : 팀 회의(역할 분담, 금일 목표 확정)
  • 11:00 ~ 12:30 : Fog of War 초기화 에러 재현 및 원인 파악(Scan Spacing Per Unit)

🍽️ 점심시간

  • 13:00 ~ 14:00 : 점심시간

✅ 오후

  • 14:00 ~ 16:30 : FogPlane 범위/위치 점검(그리드 X·Y, Mid Point, Unit Scale) 및 머티리얼 교체(Unlit)
  • 16:30 ~ 18:00 : 문 레이어( Door ) 오클루전 확인, 리빌 옵션/알파 튜닝, 전체 맵 테스트

🍽️ 저녁시간

  • 18:00 ~ 19:00 : 저녁시간

✅ 저녁

  • 19:00 ~ 20:30 : 씬 최종 점검, 설정값 가이드 정리 및 TIL 작성

✅ 오늘 학습 키워드

  • Fog of War(2D XY 변환), Level Dimension X/Y, Unit Scale, Level Mid Point
  • Scan Spacing Per Unit(샘플 간격), FogPlane 머티리얼(Unlit/Transparent), Keep Revealed Tiles
  • Door Occlusion(레이캐스트), Draw Gizmos로 범위 시각화

✅ 오늘 학습 한 내용을 나만의 언어로 정리하기

  • FogPlane은 Level Mid Point를 중심으로 Level Dimension X/Y × Unit Scale 크기로 깔리므로, 이 세 값 중 하나라도 어긋나면 맵 일부가 안개 밖으로 빠질 수 있다.
  • 안개가 “완전 검정”으로 시작하려면 Fog 머티리얼을 조명 비영향(Unlit/Transparent) 으로 써야 한다. 조명에 반응하는 머티리얼은 검정 대신 어둡게만 보일 수 있다.
  • Scan Spacing Per Unit은 0보다 커야 하며(권장 1~2), 값이 클수록 더 촘촘히 스캔하지만 비용이 늘어난다.
  • Keep Revealed Tiles를 끄면 비추기 전엔 완전 검정, 비춘 후엔 다시 덮이면 숨겨지는 “스텔스형” 연출이 된다.
  • Draw Gizmos로 그리드 박스를 확인하면 범위/중심 이상을 빠르게 찾을 수 있다.
  • 문 오클루전은 Door 레이어 + 콜라이더가 정확해야 하며, 트리거 무시는 옵션(Ignore Triggers)으로 제어한다.

🧩 학습하며 겪었던 문제점 & 에러

1) 문제정의

  • 플레이 시작 시 콘솔에에러가 발생했다.
  • Scan Spacing Per Unit must be > 0.

내가 한 시도

  • 인스펙터의 Scan Spacing Per Unit 값을 확인하고, 기존에 저장된 LevelData가 0을 들고 오는지 점검.

해결 방법

  • 인스펙터 값을 1 이상으로 수정.
  • 과거에 저장된 레벨 데이터가 있다면 삭제/수정 후 재스캔.
  • 재발 방지를 위해 코드에 최소값 강제:
// 인스펙터 실수 방지
[SerializeField, Min(1)] private int scanSpacingPerUnit = 1;

// 런타임 안전장치
void ValidateProperties()
{
    scanSpacingPerUnit = Mathf.Max(1, scanSpacingPerUnit);
}

새롭게 알게 된 점

  • 이 값은 내부에서 스캔 해상도를 결정하며, 0이면 분모가 0이 되는 계산 경로가 있어 사전에 걸러야 한다.

다시 만나게 된다면

  • 필드에 Min(1) 속성과 런타임 클램프를 함께 두고, LevelData 저장 시에도 밸리데이션 로직을 추가하겠다.

2) 문제정의

  • 벽과 문 레이어는 잘 작동하지만, 맵 오른쪽 복도가 처음부터 밝게 보이고 안개가 덮이지 않았다.

내가 한 시도

  • 레이어/콜라이더 이상 여부 확인, FogPlane 머티리얼/알파 확인, 그리드 한계선 Gizmo 확인.

해결 방법

  1. Level Dimension X/Y를 실제 맵보다 넉넉히 증가, Level Mid Point를 맵 중앙으로 재배치.
  2. 머티리얼을 URP Unlit(Transparent) 로 교체, Fog Color=검정, Fog Plane Alpha=1.
  3. Keep Revealed Tiles 끔 → 초기 완전 검정 확인.
// FogPlane 크기 재계산 예시(개념)
var size = new Vector2(levelDimensionX * unitScale, levelDimensionY * unitScale);
fogPlane.localScale = new Vector3(size.x, size.y, 1f);
fogPlane.position   = levelMidPoint.position;

새롭게 알게 된 점

  • 머티리얼이 조명 영향을 받으면 “검정”이 아닌 “어둡게”만 보일 수 있다. 또, 그리드 범위가 부족하면 특정 영역이 안개 밖으로 남는다.

다시 만나게 된다면

  • 씬 진입 시 Gizmo 박스가 맵을 완전히 덮는지 자동 점검하는 에디터 스크립트를 두고, 머티리얼 프리셋을 고정값으로 강제하겠다.

📝 메모

  • 시작값 추천: Scan Spacing Per Unit=1, Fog Lerp Speed=5, Fog Plane Alpha=1, Keep Revealed Tiles=OFF.
  • 테스트 루틴: (1) Gizmo 박스 확인 → (2) 머티리얼 Unlit 확인 → (3) 문/벽 콜라이더 및 레이어 → (4) 저장 데이터 초기화 후 재스캔.
  • 도어 오클루전은 문 사이에 아주 얇은 틈이 있으면 레이캐스트가 새어 나갈 수 있으니 콜라이더를 살짝 겹치게 배치하는 것이 안전하다.

 

반응형
반응형

🗓️ 오늘 하루 일정

✅ 오전

  • 09:00 ~ 13:00 : 발표 준비

🍽️ 점심시간

  • 13:00 ~ 14:00 : 점심시간

✅ 오후

  • 14:00 ~ 15:00 : 최종발표 전 중간발표
  • 15:00 ~ 16:00 : 휴식
  • 16:00 ~ 18:00 : 팀 회의 — 추석 연휴 개발/기획 범위 논의

🍽️ 저녁시간

  • 18:00 ~ 19:00 : 저녁시간

✅ 오늘 학습 키워드

https://youtu.be/VFJO8QlCwDA

 

중간발표


✅ 오늘 학습 한 내용을 나만의 언어로 정리하기

  • 발표는 문제–접근–결과–교훈의 4단 구조로 정리하면 이해가 빠르다. 데모는 타임라인에 맞춰 입력 시퀀스를 스크립트화해야 실수가 줄어든다.
  • 연휴 스프린트는 “핵심 루프 1분 데모”를 최우선으로 두고 나머지는 Nice-to-have로 분리한다.

🧩 학습하며 겪었던 문제점 & 에러


📝 메모

중간발표가 끝났다아!! 내일부터는 추석 시작! 각자 추석동안 개발, 기획 할거를 맡아서 진행하기로 했다. 추석 기간에도 화이팅..


반응형
반응형

🗓️ 오늘 하루 일정

✅ 오전

  • 09:00 ~ 12:00 : 인터랙션 정리(아이템: 돈/탄창 IInteractable 적용), UI 수정(F키 흰색), UIBase 두트윈 기본 비활성(로딩/게임오버/클리어/NPC)

🍽️ 점심시간

  • 13:00 ~ 14:00 : 점심시간

✅ 오후

  • 14:00 ~ 16:00 : 직렬화 충돌(triple canvasGroup) 원인 파악 및 수정, SceneInitializer 기반 UIKey 동기화 점검
  • 16:00 ~ 18:00 : 팀 PPT 제작(진행 현황, 기술적 의사결정 카드 정리)

🍽️ 저녁시간

  • 18:00 ~ 19:00 : 저녁시간

✅ 저녁

  • 19:00 ~ 21:00 : 저녁 스크럼(내일 목표 확정, 리스크 공유)
    • 영상 다시 촬영 (원테이크) (설명은 내일)
    • 발표 리허설
    • PPT 옮기기
    • 파일제출. (12시까지)
    • 발표 끝나고
      • 4차 목표에 대해서 얘기.
      • 추석간 각자 개발할거, 기획할거 나누기

✅ 오늘 학습 키워드

IInteractable · UIBase/DOTween · 직렬화 충돌 대응 · SceneManager.sceneLoaded · SceneInitializer.ActiveUI


✅ 오늘 학습 한 내용을 나만의 언어로 정리하기

  • 상호작용 규격을 IInteractable로 통일해서 문/아이템/장치 확장이 쉬워졌다.
  • UI 공통 베이스(UIBase)에서만 CanvasGroup를 직렬화하고, 자식은 프로퍼티 접근으로 통일하니 중복 직렬화 에러가 사라졌다.
  • 씬 전환 시점에 sceneLoaded 이벤트로 한 번만 SceneInitializer.ActiveUI를 읽어 UIKey를 갱신하니, 커서/BGM/UI 상태가 안정적으로 맞춰진다.

🧩 학습하며 겪었던 문제점 & 에러

1. 동일 필드명 직렬화 충돌(canvasGroup)

  • 문제정의: The same field name is serialized multiple times ... Base(SettingPopup) canvasGroup
  • 시도: 자식에서 CanvasGroup를 제거했지만 프리팹 잔여 직렬화 데이터로 계속 경고 발생.
  • 해결 방법:
    1. 부모(UIBase)만 직렬화: _canvasGroup + 프로퍼티로 접근.
    2. [FormerlySerializedAs("canvasGroup")] 추가로 레거시 매핑.
    3. 관련 프리팹 Reset로 유령 슬롯 정리.
// UIBase.cs (요지)
[FormerlySerializedAs("canvasGroup")]
[SerializeField] protected CanvasGroup _canvasGroup;
protected CanvasGroup canvasGroup => _canvasGroup;
  • 새롭게 알게 된 점: “이름이 같으면” 코드에서 지워도 프리팹 슬롯이 남아 충돌할 수 있다.
  • 다시 만나면: 부모 직렬화 필드명은 접두어(_) 규칙으로 고정한다.

2. 씬 전환 후 UIKey 불일치

  • 문제정의: 씬이 바뀐 뒤 커서/BGM/UI가 현재 씬 컨텍스트와 다르게 뜨는 현상.
  • 시도: 임의 시점에서 FindFirstObjectByType 호출 → 타이밍 이슈로 누락.
  • 해결 방법: 씬 로드시 한 번만 갱신.
// MissionManager.cs (핵심)
void OnEnable()  => SceneManager.sceneLoaded += OnSceneLoaded;
void OnDisable() => SceneManager.sceneLoaded -= OnSceneLoaded;

void OnSceneLoaded(Scene s, LoadSceneMode m){
    var init = FindFirstObjectByType<SceneInitializer>(FindObjectsInactive.Include);
    if (init) UIKey = init.ActiveUI;
}
  • 새롭게 알게 된 점: 컨텍스트 갱신은 “이벤트 기준”이 가장 안전하다.
  • 다시 만나면: 전역 UIContext로 브로드캐스트 구조 도입.

📝 메모

  • 오늘은 규약 정리가 큰 성과다. 인터랙션/UI/씬 컨텍스트가 한 흐름으로 정리되니 마음이 훨씬 편하다.
  • 내일은 PPT에 기술적 의사결정(LoadingFlow, UIContext, FoW) 사례를 짧고 강하게 넣자.

반응형
반응형

🗓️ 오늘 하루 일정

✅ 오전

  • 09:00 ~ 10:30 : UIBase에 DOTween 프리셋(오픈/클로즈+유틸) 설계 정리
  • 10:30 ~ 12:00 : 로딩 화면 구조 재설계(전용 카메라/레이어 분리 초안)

🍽️ 점심시간

  • 13:00 ~ 14:00 : 점심시간

✅ 오후

  • 14:00 ~ 16:30 : LoadingCanvas 구현 보강(활성 보장, 최소 2초 노출) · UIRoot.HideAllSceneUIs() 추가
  • 16:30 ~ 18:00 : 로딩 전용 카메라 세팅(SS-Camera, CullingMask) 및 씬 전환 흐름 점검

🍽️ 저녁시간

  • 18:00 ~ 19:00 : 저녁시간

✅ 저녁

  • 19:00 ~ 20:30 : Dimmer 색감/알파 수정, 팝업들에 DOTween 적용
  • 20:30 ~ 21:00 : QA 피드백 반영/커밋
    • [Fix] Loading 2초로 수정
    • [Fix] UI Dimmer 색 수정
    • [Fix] UIBase 두트윈 추가

✅ 오늘 학습 키워드

  • DOTween 프리셋(Scale/Fade/Slide/Drop, Pulse/Shake/Punch)
  • CanvasGroup · Dimmer(블록/페이드 분리)
  • LoadingCanvas(독립 카메라/레이어, 최소 노출, 비동기 로드)
  • UIRoot.HideAllSceneUIs() · 씬 전환 시 UI 상태 관리
  • SceneManager.sceneLoaded 훅 · DontDestroyOnLoad 싱글톤 초기화
  • 카메라 Culling Mask / Screen Space - Camera

✅ 오늘 학습 한 내용을 나만의 언어로 정리하기

  • UI 연출을 공통화하면 개별 UI 스크립트가 단순해진다. UIBase에서 프리셋만 바꿔도 일관된 퀄리티를 유지할 수 있다.
  • 로딩 화면은 씬 카메라와 분리해야 안정적이다. 전용 카메라 + 전용 레이어로 그리면 어떤 씬/카메라 구도에서도 동일한 연출을 보장한다.
  • 씬 이동 중에는 현재 씬 UI를 일괄 숨김 → 로딩만 노출 → 새 씬 SceneInitializer가 ShowOnly(activeUI)로 정리.
  • Dimmer는 입력 차단(blocksRaycasts)시각(Fade) 을 분리해 제어하면 버그가 줄어든다.

🧩 학습하며 겪었던 문제점 & 에러

1) Coroutine couldn't be started ... 'LoadingCanvas' is inactive!

  • 문제 정의: 비활성 오브젝트에서 코루틴 시작 시 예외 발생.
  • 시도: OpenUI() 호출 순서 조정, SetActive(true) 보장.
  • 해결 코드:포인트: 로딩 GO는 비활성로 숨기지 말고 CanvasGroup.alpha=0로 숨기는 편이 안전.
  • public static Coroutine LoadScene(string name) { if (!Instance.gameObject.activeSelf) Instance.gameObject.SetActive(true); if (!Instance.enabled) Instance.enabled = true; return Instance.StartCoroutine(Instance.CoLoad(name)); }
  • 새롭게 알게 된 점: StartCoroutine은 활성 컴포넌트에서만 동작.
  • 다시 만나면: 공용 오버레이는 항상 활성 유지 + 알파로 제어.

2) 로딩 화면 구도가 씬마다 달라서 오브젝트가 화면 밖으로 벗어남

  • 문제 정의: 로딩 중 월드 오브젝트(플레이어 스프라이트/타일)가 메인 카메라 구도에 의존.
  • 해결: 로딩 전용 카메라로 분리, 해당 오브젝트는 LoadingWorld 레이어로 렌더.
  • // Awake in LoadingCanvas overlayCanvas.renderMode = RenderMode.ScreenSpaceCamera; overlayCanvas.worldCamera = loadingCamera; loadingCamera.cullingMask = LayerMask.GetMask("LoadingWorld"); loadingCamera.depth = 1000; // 항상 최상단
  • 새롭게 알게 된 점: 오버레이는 카메라 독립성이 핵심.
  • 다시 만나면: 전용 카메라 + 전용 레이어 설계부터 시작.

3) 로딩 중 플레이어 공격 SFX가 들림

  • 문제 정의: 씬 교체 중 입력/애니메이션 잔재로 SFX 출력.
  • 해결(믹서 파라미터 뮤트):
    • UIRoot.HideAllSceneUIs()로 UI 정리, 필요 시 PlayerInput.enabled = false 병행.
  • // OnOpen / OnClose in LoadingCanvas mixer.GetFloat("SFXVol", out prev); mixer.SetFloat("SFXVol", -80f); // 로딩 시작 시 // ... mixer.SetFloat("SFXVol", prev); // 로딩 종료 시
  • 새롭게 알게 된 점: 오디오는 스냅샷/파라미터 방식이 가장 안정적.
  • 다시 만나면: 로딩 시작 훅에서 입력/사운드 모두 차단.

📝 메모

오늘은 UI 공통화(DOTween)로딩 파이프라인 안정화 두 축을 확실히 잡았다.

디테일(딤머 색·알파, 최소 노출 2초)까지 손보고 나니 화면 전환이 훨씬 매끈해졌다.

내일은 로딩 중 SFX 완전 차단과 스태미나 초기화, 커서 정책을 마무리하고 스테이지2 잔업을 닫자.

내일도 화이팅!!!


 

반응형
반응형

🗓️ 오늘 하루 일정

✅ 오전

  • 10:00 ~ 11:00 : 최종 프로젝트 발제 진행
  • 11:00 ~ 12:00 : UI 버그타이틀 사운드 버그 수정

🍽️ 점심시간

  • 13:00 ~ 14:00 : 점심

✅ 오후

  • 14:00 ~ 16:00 : NPC 대사 컨텍스트 설계(FirstMeet/Fail/Clear 등) 초안 → 보류/원복 결정
  • 16:00 ~ 18:00 : 씬 전환 로딩 흐름 검토
    • SceneLoader/SceneInitializer로 2초 노출 후 전환 시나리오 작성
    • 최종적으로 로딩 씬 대신 “UI 오버레이” 방식으로 전환 결정

✅ 저녁

  • 19:00 ~ 21:00 : 로딩 UI 연출 기획
    • Shift 애니메이션 이벤트(AE_RunOn/AE_RunOff)로 Run 토글 + 스태미나 바 증감 데모 설계
    • DOTween 트랜지션(암살/어두움/거친) 구상, Laser Wipe(좌→우) 프로토타입 → 내일 적용으로 연기

✅ 오늘 학습 키워드

  • UI 오버레이 기반 로딩 연출(비동기 로드 + 최소 노출 시간 보장)
  • 애니메이션 이벤트로 상태 연동(Run Bool, 스태미나 증감)
  • RectMask2D 와이프 연출의 앵커/피벗 설계(좌측 고정)
  • DOTween 시퀀스 SetUpdate(true)(unscaled 타임) 활용
  • 씬 전환 설계 의사결정: 로딩 씬 vs 로딩 UI

✅ 오늘 학습 한 내용을 나만의 언어로 정리하기

  • 로딩은 씬 갈아타기보다 UI 오버레이가 유지보수에 유리했다. 동일 씬 내에서 비동기 로드를 돌리고 최소 2초 노출만 보장하면, 전역 상태나 입력 차단도 한 곳에서 관리 가능했다.
  • 입력 없이도 애니메이션 이벤트만으로 Run 상태와 스태미나 바를 자연스럽게 연동할 수 있었다. 로딩 데모엔 이게 가장 단순하고 견고했다.
  • Laser Wipe(좌→우 채움)는 본체가 아니라 마스크 컨테이너anchorMin(0,0) / anchorMax(0,1) / pivot(0,0.5) 가 핵심이었다. 이걸 틀리면 “가운데에서 양쪽 확장”으로 보인다.
  • unscaledDeltaTime 기반으로 트윈을 돌리면 로딩/일시정지에서도 연출이 끊기지 않는다.

🧩 학습하며 겪었던 문제점 & 에러

1) Laser Wipe가 중앙에서 양쪽으로 벌어짐

  • 정의: 좌→우 채움이 아닌, 중앙 기준으로 확장되는 현상
  • 시도: 트윈 이징/스케일 조정, 마스크 크기 수동 세팅
  • 해결: RectMask2D 컨테이너를 좌측 고정(anchorMin=(0,0), anchorMax=(0,1), pivot=(0,0.5)) 으로 강제. Edge 이미지는 우측 고정으로 이동
  • 새롭게 알게 된 점: 와이프 방향은 마스크 컨테이너의 기준점에 의해 결정된다
  • 다시 만나면: 초기화 단계에서 앵커/피벗을 코드로 강제 세팅하고, LayoutRebuilder.ForceRebuildLayoutImmediate로 치수 확정 후 트윈 시작

2) 로딩 흐름(로딩 씬 vs UI) 의사결정 충돌

  • 정의: SceneInitializer 코루틴 방식(로딩 씬 2초 노출)과 UI 오버레이 방식 중 무엇을 쓸지 혼선
  • 시도: SceneLoader + SceneInitializer로 2초 보장 구현 → 호출부 치환 부담 발생
  • 해결: 로딩 UI 오버레이로 전환(입력 차단/연출/최소 노출을 한 곳에서 처리)
  • 새롭게 알게 된 점: 씬 간 공용 규칙이 많을수록 UI 오버레이가 변경 비용이 낮다
  • 다시 만나면: 초기에 전역 오버레이 1개를 DontDestroyOnLoad로 두고, 라우팅은 유지하되 UI가 최종 제어

📝 메모

  • 내일: 로딩 오버레이 실제 적용(2초 보장 + allowSceneActivation 타이밍), Laser Wipe(좌→우/우→좌) 트윈 값 튜닝, “암살/거친/느와르” 톤 프리셋화
  • 대사 컨텍스트 로직은 스펙 유지, 구현은 배치 안정화 후 재개
  • 오버레이에서 CanvasGroup.blocksRaycasts로 입력 차단 표준화, 사운드/블룸으로 연출 보강

반응형