Null — 개발 TODO
체크 상태는 브라우저 로컬 스토리지에 자동 저장됩니다.
9년 전, 현은 연서에게 우산을 씌워줬다.
9년 후, 그는 그 이유를 모른 채 돌아온다.
단도와 블링크로 싸우는 사이버네틱 요원.
복종 회로, 설계된 감정, 그리고 빨간 우산 하나.
설계든 아니든, 지금 이 마음은 내 거야.
체크 상태는 브라우저 로컬 스토리지에 자동 저장됩니다.
2D 액션 플래포머 · 횡스크롤 · 스토리 위주
Unity 2D · 1인 개발 기준 · 챕터 12개 완전 설계
셧다운 프로토콜. 복종 회로 전체 비활성화. 경고: 대상자 사이버네틱 전체 정지 포함.
2026.03.28 ~ 진행 중 · Unity 2D · 1인 개발
Dagger & Blink — 투사체 기반 위치 이동 시스템 기틀 마련.
공중 블링크 1회 제한 — 착지/벽 점착 시 리셋. 무한 체공 방어.
Hit-Stop — 블링크 직후 시간 왜곡, 공간 절단 타격감.
Ghost Fade — 검붉은 #800000 잔상, 누아르 톤 비주얼 피드백.
I-frame — 이동 경로 및 도착 직후 짧은 무적 프레임.
발·허리·머리 높이에서 좌우 6개 레이로 연속된 벽을 정밀 감지. 반쪽 벽 매달리기 시각 버그 방어.
벽 부착 상태에서 W/S 키 자유로운 상하 이동 구현 gravityScale = 0.
벽 점프 시 반대 방향 힘 + 0.15초 입력 잠금. 조작의 쫀득함과 수직 상승 버그 동시 방어.
벽에 붙는 순간 공중 블링크 횟수 즉시 초기화. 벽-블링크-벽 무한 기동 발판 마련.
Grounded / Air / WallClimb 상태 명확 분리. 복합 이동 상황에서도 물리 로직 충돌 없음.
Player, Dagger, Wall, Ground 간 상호작용 우선순위 확립.
공중 1회 제한 해제 → Time.time 기반 0.5초 쿨타임. 사슬팔 스윙 같은 연속 기동 확보.
공중 무한 투척 시 제자리 체공 방지. 투척 순간 velocity.y 강제 하강 → 묵직한 조작감.
단검이 Enemy 레이어 충돌 시 Shift 없이 TryBlinkToDagger 자동 호출. 편의성·속도감 극대화.
LineRenderer로 적↔플레이어 실시간 거리·방향 레이저 시각화.
텍스트 인디케이터 '나 여깄어!' 구현 후 시각적 노이즈 판정으로 비활성화.
RigidbodyType2D.Dynamic 기본 중력으로 단검이 포물선 낙하. → Launch 시 rb.gravityScale = 0f 강제 주입, 직진 궤적 완성.Project 창(창고) vs Hierarchy(무대) 구조 이해. Unlit/Transparent·Sprites/Default 쉐이더 특성 및 텍스처 타일링 확립.
기존 3D 기반(Vector3, RaycastHit) 인터페이스 폐기 → Vector2 및 Collision2D 사용 2D 전용 계약 재정의.
3D Rigidbody 의존성 완전 제거 → Rigidbody2D 기반 표준화. IProjectile2D 구현, EffectManager와 정상 연결.
베이스 클래스와 인터페이스를 실제 동작부와 연결 — 아키텍처 정합성 확보.
DaggerProjectile2D.Awake에서 PlayerBlinkController2D 1회 캐싱, Launch 시점 null 재확인 이중 방어막. 매 충돌 씬 전체 탐색 오버헤드 제거.
문자열 비교 방식 지양 → static readonly int 상수 시스템. 오타로 인한 Silent Bug 원천 차단. 비트 연산 기반 레이어 마스크로 교체.
EffectManager.SpawnEffect 호출 시 ps.main.duration + 유예 시간 즉시 파괴 로직. 장시간 파티클 오브젝트 누적 크래시 리스크 해결.
단검 적중 시 외부에서 즉시 호출 가능. 공중 블링크 소모 규칙·코요테 타임 준수하며 속도감 있는 기동 가능.
----) 스프라이트 제작.cursorrules 2.0 도입에 따른 전역 코드 감사 및 성능 최적화.하드코딩 수치(쿨타임·히트스톱·오프셋 등) → WeaponData.cs로 이관. 밸런싱 효율 증대.
string 기반 레이어 비교 완전 제거 → Layers.cs 정적 상수. 오타 물리 버그 원천 차단.
블링크 이펙트 Instantiate 시 Destroy(go, duration) 명시 → 메모리 누수 방지.
Update 내 .material 접근 시 매 프레임 인스턴스 생성 유니티 고질 문제 해결.Awake에서 1회 캐싱, OnDestroy에서 명시적 Destroy(_cachedMaterial) 호출.
인스펙터 할당 우선 → 누락 시에만 FindFirstObjectByType 호출. 런타임 부하 최소화 + 경고 로그 추가.
LogError/Warning 처리new 할당 및 문자열 생성 지양| 메카닉 | 설명 |
|---|---|
Blink 순간이동 | 투사체 패링 시 즉시 충전되는 초고속 이동기 |
Grab 제압 | 적의 약점을 낚아채어 물리 소유권 강제 획득 |
Slam 강타 | 적을 지면에 메쳐 광역 데미지와 아머 파괴 피니셔 |
IGrabbable Interface — 모든 적·보스 약점을 하나의 인터페이스로 통합, 저결합도 달성.ArmorGauge System — 일반 공격 차단, Blink/Slam으로만 파괴 가능한 가드 + 자동 재생.
_target == null 시 무한 대기 → 즉시 IdleState 복귀 탈출로 확보._hasImpacted 플래그 초기화를 Enter() 최상단으로 이동. 조기 리턴 시 물리 오발사 방지. _rb·_target null 가드 강화.PlayerBlinkController2D 모든 입력 차단. 블링크 중복 발사 Self-Transition 버그 차단.| 단계 | 보스명 | 핵심 기믹 | 서사 |
|---|---|---|---|
| 01 | 하운드 | 블링크 입문 / 유압 피스톤 그랩 | 분노 |
| 02 | 서류 | 패리 + 블링크 (탄막 대응) | 무력감 |
| 03 | 형 | 단검 박고 강제 블링크 탈출 | 혼란 |
| 04 | 그림자 | 비전투 퍼즐 / 잔상 스위칭 | 수용 |
| 05 | 설계자 | 군단 소환 / 역패리 대응 | 선택 |
PlayerMovement2D와 PlayerStateMachine의 레이어 마스크 이중화. 인스펙터에서 동일한 Ground 레이어 확인 필수. (차후 전역 상수 통합 예정)
| 클래스 | 설명 |
|---|---|
EnemyBossHound | 유압 피스톤 그랩 + 블링크 입문 |
HoundShockwaveState | 슬램 충격파 |
| 클래스 | 설명 |
|---|---|
EnemyBossPaper | 드론 방패 + 도장 패턴 허브 |
PaperDrone | 패리 유도 드론 |
PaperDroneShieldState | 드론 전멸 시 PaperOverclockState 전이 |
PaperStampState | 지면 Raycast 방어 포함 |
PaperOverclockState (P2) | 4발 바라지 + 각도 퍼짐 |
| 클래스 | 설명 |
|---|---|
EnemyBossBrother | LastPlayerBlinkPos 추적 |
BrotherBindProjectile2D | 구속 와이어 |
BrotherCounterState (P2) | 블링크 위치 텔레포트 후 즉각 슬래시 |
PlayerBoundState | 전면 재작성 |
| 클래스 | 설명 |
|---|---|
EnemyBossShadow | LRU 마커 관리 + Bind/Unbind 오버라이드 |
BlinkGhostMarker | Pause/Resume + 즉각 겹침 감지 |
GhostSwitch | HashSet 추적 + IsFake (Phase 3 가짜 스위치) |
ShadowGhostPhaseState | 퍼즐 타임아웃 |
ShadowHauntState | 절대 타이머 + FadeAndWarpRoutine |
| 클래스 | 설명 |
|---|---|
EnemyBossDesigner | Wave 13 + Phase 12 허브 |
DesignerUmbrella | 단검 반사 Anti-Blink — 핵심 메카닉 |
ArmJoint | 관절 파괴 (원본 disabled + 분리 프리팹) |
EliteAgent / NullCyborg / EliteZeroX01 | Wave 적 3종 |
DesignerWaveState | Wave 1→2→3 시퀀서 |
DesignerStruggleState | 동시 대치 + ForcedReleaseTimer |
| Ending A | Ending B | |
|---|---|---|
| 선택 | 연서가 USB를 막는다 | 연서가 USB를 직접 누른다 |
| 결말 | 빨간 우산 아래 둘이 서있음 — "현아." | 우산이 바닥에, 혼자 빗속 |
| 톤 | 희망 | 비극 |
CutscenePlayer — 라인바이라인 나레이션 엔진.EndingChoiceUI — 분기 선택지 UI.EndingUSBItem — 공통 프리 컷씬 + Ending A/B 전체 대사 내장.
| 레벨 | 종류 | 동작 |
|---|---|---|
| 1 | Ambient | 낮은 우선순위, 큐 드롭 허용 |
| 2 | Combat | 전투 상황 자막 |
| 3 | Story | 강제 재생, 드롭 불가 |
| 패키지 | 버전 | 효과 |
|---|---|---|
com.unity.ugui | 2.0.0 | UI 누락으로 발생하던 CS0246 등 완화 |
com.unity.textmeshpro | 3.0.9 | TMP 참조 복구 |
| 파일 | 증상 | 조치 |
|---|---|---|
ArmJoint.cs | CS0108 — gameObject 부모 충돌 | new 키워드 정리 |
DaggerProjectile2D.cs | 존재하지 않는 필드 참조 | weaponData.speed → projectileSpeed |
StoryDatabase.cs | CS0103 Debug 미인식 | using UnityEngine; 추가 |
BossStateMachine | void 대입 CS0815 | 반환형 BossParryableProjectile2D로 명시 |
| DesignerWaveState 외 3종 | ?? 좌우 타입 불일치 | (… as IBossState) ?? … 형태로 통일 |
CombatDialogueUI.cs | CS0414 미사용 필드 | DialoguePriority.Combat 분기에서 사용으로 해소 |
Layers.PlayerPhysicsGroundMask — Ground 레이어 단일 비트 추가.
적용: PlayerMovement2D, PlayerStateMachine → SlamState, PlayerBlinkController2D.
인스펙터 groundMask가 비어 있으면 폴백 사용 → 이중 설정 불일치 완화.
풀 프리팹 == WeaponData.daggerProjectilePrefab 일 때만 Get / Release.
불일치 시 LogWarning 후 Instantiate 폴백.DaggerProjectile2D.SetReleasePool, ReleaseToPoolOrDestroy() — 최대 사거리·블링크 회수 시 반환.
| API | 연결 지점 |
|---|---|
PlayBlink() | TryBlinkToDagger 성공 시 |
PlayGrab() | GrabState.Enter |
PlaySlam() | SlamState.ExecuteImpact |
PlayParry() | PlayerParryController2D.OnParrySuccess |
PlayDeath() | PlayerHealth.Die (_sfxDeath 슬롯 추가) |
Player_Idle / Player_Run / Player_BlinkCombat / Player_Grab / Player_Slam / Player_Bound
각 State Enter()에서 대응 트리거 발행.
Int BossPhase, Trigger BossGrabbed / BossVulnerable
페이즈 전환 시 SetInteger, GrabbedState·VulnerableState 진입 시 SetTrigger.
Animator 미할당 시 동작 변화 없음.
| 항목 | 내용 |
|---|---|
| 상황 | feature/Unity rebase 중 README.md both modified |
| 조치 | 2026-04-03 devlog 링크 세 줄 병합 (Unity_Error_Fix 등) |
| 결과 | rebase 완료 |
| 파일 | 내용 |
|---|---|
PlayerBlinkController2D.cs | OnBlinkExecuted 중복 summary 제거 |
DaggerProjectile2D.cs | 지면 튕김·미끄럼 완화: Continuous 검출, 무탄성 PhysicsMaterial2D, PinToContact, 임베드 시 각속도·회전 고정 |
WeaponData.cs | daggerPhysicsMaterial, daggerSurfaceEmbedInset 추가 |
| 경로 | 내용 |
|---|---|
Assets/Scenes/ | TestScene.unity 이동, Test_Arena.unity 추가 — 그레이박스·전투 테스트용 |
Assets/Art/Sprites/ | spr_Tile_Base.png 추가 |
Assets/Data/ | NewWeaponData.asset 이동 |
Assets/Scripts/ | Layers.cs, WeaponData.cs, MovementData.cs 등 베이스 스크립트 이동 (루트 혼잡 감소) |
Assets/Sound/ | 폴더 생성 — SFX 연결 예정 |
| 삭제 | Assets/GroundPalette.prefab, 루트 NewWeaponData.asset |
| 항목 | 내용 |
|---|---|
| com.unity.2d.pixel-perfect 5.1.1 | 픽셀 아트 카메라 정수 스케일 등 |
| Physics2DSettings | 물리 2D 설정 조정 |
| TagManager | 레이어·태그 씬과 맞춤 정리 |
| 구간 | 내용 |
|---|---|
X = 0 ~ 40 학교 정문 | 감정적 몰입을 위한 적막한 빗길 구간 |
X = 40 목표 지점 | 연서(NPC) 배치, 처마 Y = 4 레이아웃 |
X = 42 물리 차단 | 이벤트 전 무단 이탈 방지 — Obj_StoryGate_School |
X = 70 점프 튜토리얼 | 3칸 규격 Gap — 기본 도약 메커니즘 검증 |
X = 100 분식집 랜드마크 | 10×6 거대 매스, 두 번째 시퀀스 도달점 |
홀수 해상도 경고(593×333) → 16:9 고정 + 정수 배율 1280×720으로 픽셀 뭉개짐 방어.
Deep Black #06060a로 픽셀 실루엣 대비 강화.
World Space 파티클 — 중력 1.5, 낙하 속도 20, Stretched Billboard로 빗줄기 질감. 환경 연출 ~90% 완료.
| 항목 | 내용 |
|---|---|
| 제어권 분리 | SetStoryInputLocked — 컷씬·연출 중 돌발 입력 방어. PlayerMovement2D, Blink, Parry 전체 적용. |
| 트리거 | X ≈ 37 OpeningEventController로 연출 시작 시점 동기화 |
| 착지 후 잠금 | 공중 트리거 시 부유 방지 — WaitUntilPlayerFloored 계열 |
| 입력 억제 | 해제 직후 튐 완화 — 수평 입력 억제 ~0.08s + Input.ResetInputAxes() |
| NPC 동행 | NPCFollow2D — 플레이어 대비 1.2× 속도, Follow Distance 1.5 |
| 항목 | 내용 |
|---|---|
| PPU / 픽셀 | hold 스프라이트 PPU 16 (1px = 0.0625). 펼침(open/pull)만 PPU 8 (1px = 0.125). 상수: OnePixelWorldUnitUmbrellaHoldPpu16 / OnePixelWorldUnitUmbrellaPullPpu8 |
| 스미어 | Stretch Y 0.1 → 1.2, 0.05s, SmoothStep 적용 — 정점에서 기계적 선형 느낌 완화 |
| 무게 중심 | VisualRoot 로컬 Y _bounceVisualLocalY — 기본 −0.125(open/pull PPU8 기준 1px) + 팔로우스루로 원복 |
| 착지 스냅 | 타임아웃 Y 스냅 직후 1프레임 _landingSnapMicroBounceLocalY — 기본 −0.0625(hold PPU16 기준 1px) |
| Z 파이팅 | 우산 SpriteRenderer 로컬 Z −0.01 연출 구간 적용 후 원복 |
| Animator | _storyVisualAnimator None 허용. null 가드로 speed 조작만 수행 |
물리 콜라이더와 시각 에셋 분리 — 우산 펼침 시 바운스·스쿼시가 본체 물리에 덜 미치도록.
캐릭터 10 / 우산 11 순서 확정 — 실루엣·간섭 방어. 그레이박스 씬에 연결 완료.
| 영역 | 상태 |
|---|---|
| 월드 좌표 설계 | ~100% |
| 환경 연출 (비·배경) | ~90% |
| 입력 제어·오프닝(우산) | 기준선 완료 |
| 우산 스프라이트·하이어라키 | 그레이박스 연결 완료 / 폴리싱 진행 중 |
| 분식집 '정지' 연출 | 0% — 공간 O, 무입력 씬 로직 X |
| 가을 골목·인생네컷·전투 튜토 | 미착수 (다음 웨이브) |
SnackShopStoryController 분리 권장feat: umbrella sequence pixel grid + opening story lock
PlayUntil), 트리거로 재개(ResumeFromID)하는 감독 / 서사 / 물리 경계를 정리한 날.
| 구분 | 작업 내용 | 달성 · 의도 |
|---|---|---|
| 시스템 구축 | GameInitializer.cs 추가 |
씬 진입 시 Chapter1_Opening JSON 로드 → PlayUntil(22)로 22번 라인까지 자동 재생 후 WaitingForTrigger 대기. Start()는 1프레임 양보 + 선행 유예(기본 0.15s) 후 ResolveAndPlay(). |
| 방어 설계 | CutscenePlayer.PrepareStoryUiForResume() |
ResumeFromID 직전 Narration/Dialogue CanvasGroup 활성화 + alpha 1. _fadeOverlay(Canvas_Fade)가 암전(~1)으로 남은 경우 alpha 0·비활성으로 잔상 제거. |
| 지휘권 정리 | 트리거·초기화 역할 분리 | GameInitializer가 시작 대사를 담당하고, 물리 트리거는 ResumeFromID(23) 등 전환만 담당. 스폰 인접 이중 점화·인덱스 꼬임·교차 보행 위험 문서화. |
| 시각·텍스트 | TMP · 레이아웃 | 나레이션 줄바꿈(JSON \n) → 공백 합치기 옵션, 화자–본문 구분 문자, 인스펙터 Header 라벨 정리. 폰트·레이어는 씬에서 수동 할당 전제(잔존 이슈). |
| 파일 · 컴포넌트 | 역할 |
|---|---|
Assets/Story/GameInitializer.cs | 씬 진입 시 스토리 키·PlayUntil lineId 로드·실행. UnityEvent용 ResolveAndPlay(). ChapterStoryLoader와 동일한 JSON 분기. |
Assets/Scripts/IPlayerCutsceneHandoff.cs | SetCutsceneMode / InjectVirtualInput 계약. |
Assets/Story/StoryEventTrigger.cs | OnTriggerEnter2D + CompareTag("Player") → 1회 발동 후 Collider 비활성. |
Assets/Player/PlayerMovement2D.cs | 컷신 모드·가상 입력·ApplyResumeInputSuppressPulse·FSM용 GetMovementHorizontalAxis. |
Assets/Player/PlayerBlinkController2D.cs | SyncCutsceneMode, ApplyResumeInputSuppressPulse. |
Assets/Player/PlayerParryController2D.cs | 컷신·재개 입력 억제 중 패리 차단. |
Assets/Player/PlayerStateMachine.cs | GetMovementHorizontalAxis(), PlayerMovement 노출. |
Assets/Player/States/IdleState.cs / RunState.cs | 실제 축을 머신 경유로 통일. |
Assets/Player/States/BlinkState.cs | 컷신 중 Shift 블링크 차단. |
Assets/Ending/CutscenePlayer.cs | CutsceneState, PlayUntil / ResumeFromID, PrepareStoryUiForResume, 라인 ID UnityEvent 훅, 재개 입력 억제 코루틴, PlayNextLine + Context Menu 등. |
OpeningEventController는 우산 스쿼시·NPC 추적 등 연출 전용(Anticipation ~0.2s, Smear ~0.05s, Follow Distance 등)으로 기존대로 유지. 오프닝 대본의 "언제까지 읽을지"는 GameInitializer + CutscenePlayer 조합으로 분리.
| 축 | 가설 | 검증 포인트 |
|---|---|---|
| 교차 보행 | 카메라 Culling Mask에서 UI 레이어 미포함 | Main / UI Camera가 UI 레이어를 렌더하지 않음 → 로직상 켜져도 화면에 안 보임. |
| 무게 중심 | 데이터–TMP 참조 단절 | 인스펙터에 Body_Text 등이 "New Text" 미교체, 또는 ResumeFromID(23) 시점에 JSON id 23 라인 부재·파싱 오류로 텍스트 주입 전 중단. |
| 회수 / 스미어 | Sorting Order · Canvas 순서 | Canvas_Fade 또는 배경 Canvas가 Canvas_Dialogue보다 위에 있어 글자가 뒤에 가림. |
PrepareStoryUiForResume으로 패널·전역 Fade 오버레이는 한 번 더 정리했으나, 별도 FadeManager 전용 오버레이·카메라 마스크·소팅은 씬 데이터 점검이 필요하다.
Chapter1_Opening.json에서 id 23 라인 존재·타입·text 필드 형식 확인.Canvas_Dialogue(또는 동일 역할 Canvas)의 Sort Order를 전면 Fade·월드보다 충분히 높게(예: 100+) 설정.StoryEventTrigger와 GameInitializer의 PlayUntil이 같은 대사를 이중 점화하지 않도록, Resume·전환은 한 트리거에만 연결하고 스폰과 콜라이더 겹침을 피할 것.
Anticipation Hold 0.2s · Smear 0.05s · Follow Distance 1.5
Restore Player Control 켜서 시퀀스 후 조작권 복귀 확인.
| 영역 | 경로 |
|---|---|
| 오프닝 JSON | Assets/Resources/StoryData/Chapter1_Opening.json |
| 감독 진입 | Assets/Story/GameInitializer.cs |
| 컷신 재생기 | Assets/Ending/CutscenePlayer.cs |
| 조작 Handoff | Assets/Scripts/IPlayerCutsceneHandoff.cs, Assets/Player/PlayerMovement2D.cs |
| 공간 트리거 | Assets/Story/StoryEventTrigger.cs |
| JSON 로더 | Assets/Dialogue/StoryJsonManager.cs, ChapterStoryLoader.cs |
| 우산 연출 | Assets/Story/OpeningEventController.cs |
| 증상 | 가설 (1순위) |
|---|---|
| 씬 시작 직후 컷씬이 안 돌아감 | 선행 동작 부재 — ChapterStoryLoader가 Awake에서 JSON을 주입하지만, TriggerCutscene을 즉시 점화하는 코드가 먼저 돌면 리스트가 비거나 레이스 컨디션 발생. |
| 한글 폰트 베이킹 시 에디터 프리징 | 타이밍/부하 — Dynamic/OS 기본 세트 전체를 한 번에 구우면 불필요한 글리프 범위로 연산 폭발 → 체감 ~2시간 멈춤. |
Assets/Resources/StoryData/Chapter1_Opening.json — StoryDatabase.GetChapter1Lines()를 한글·줄바꿈 포함 이전.
Resources.Load<TextAsset> + JsonUtility. 라인별 공백 제외 26자 초과 시 LogError로 즉시 알림.
오프닝 구간 — line id 53(FadeIn)까지만 리스트에 담고, 이후 라인은 다음 씬용으로 분리.
CutsceneLine.lineId — id 43 의성어「꼬르륵」 / id 53 암전 종료를 코드에서 구분.
IEnumerator Start()에서 0.1s 대기 후 TriggerCutscene.Play() 호출.
같은 프레임에 JSON 주입과 컷씬 점화가 붙지 않도록 버퍼를 둔 것이 핵심.
TriggerCutscene에 Play() → ActivateTrigger() 공개 API 추가 — 충돌 없이 강제 점화.
| 항목 | 내용 |
|---|---|
| 오프닝 전용 물리 주입 | BeginOpeningSequencePhysics / EndOpeningSequencePhysics |
| 초기 설계 | 느린 누아르 질감 (move 2.2) |
| 플레이 검증 후 조정 | 그레이박스 장애물 통과 불가 → move 3.5 / jump 10으로 수정 |
| 안전 기본값 | 복구 실패 시 move 4 / jump 12 |
| 걷기 전용 잠금 | walkOnlyNoJump — 스토리 구간 점프 연타로 트리거 스킵 방어 |
OpeningSequencePhysicsDefaults에 상수화.CombatDialogueUI.ShowAmbientOnomatopoeia — 배경 알파 스케일·본문 색 톤 다운, TMP rich text 이탤릭.
FadeManager — CanvasGroup으로 암전, blocksRaycasts/interactable로 입력 차단.
FinalizeOpening 이벤트로 1장 시퀀스 종료 + 제어권 정리.
Dynamic/OS 기본 세트 전체 → 필요 글리프만 제한으로 전환.
연산 시간: ~2시간 → 449ms (99% 이상 단축).
타협이 아니라 필요 글리프만 조준한 데이터 설계 = 정밀 사격.
| 원칙 | 적용 |
|---|---|
| 선행 동작 | JSON 주입 이후를 고려한 0.1s 대기 + 트리거 강제 점화 순서 고정 |
| 타이밍 | 컷씬 라인 duration·Fade 0.9s와 FadeManager 기본 암전 시간 정렬 |
| 스미어/가독성 | 의성어 라인 패널·텍스트 대비 조정, Padding 5px 아웃라인 실험 |
| 무게 중심 | UI 앵커 (0,0) 레이아웃이 연출과 겹치는지 확인 — 내일 수정 예약 |
| Follow-through | JSON 파싱 실패 시 Missing Data 대사, 물리 복구 실패 시 기본 수치, 암전 후 FinalizeOpening으로 제어권 정리 |
CutscenePlayer.cs — 암전 잔상 조건 오류문제: PrepareStoryUiForResume에서 _fadeOverlay.alpha > 0.99f만 체크 → 페이드가 중간(0.01~0.98)에서 멈추면 화면이 어둡게 남음.
수정: 기준을 > 0.01f로 변경 — 조금이라도 암전 흔적이 있으면 즉시 제거.
CutscenePlayer.cs — _skipCurrentLine 플래그 이중 소비문제: Update(HoldWithSkip용)와 ShowConfirm(WaitUntil용)이 같은 _skipCurrentLine을 공유 → 라인 이중 소비·타이밍 꼬임 가능.
수정: ShowConfirm 전용 _confirmWaitInputReady 플래그 분리.
StoryEventTrigger.cs — Rigidbody2D 미전제문제: OnTriggerEnter2D는 양쪽 중 하나에 RB가 있어야 발생 — 플레이어 RB 없으면 트리거 자체가 무음 실패.
수정: Awake에서 RB 미할당 경고 추가. 검증 로직을 IsPlayer() 메서드로 분리, Tag + Layer 이중 검증 적용.
StoryJsonManager.cs — JSON type 오타 시 조용한 폴백문제: ParseLineType 기본값이 항상 Narration → JSON에 오타가 있어도 경고 없이 잘못된 연출 실행.
수정: 알 수 없는 타입 시 Debug.LogWarning 출력 후 폴백.
PlayerBlinkController2D.cs — 무적 레이어 복구 오류문제: PerformBlinkInvincibility에서 origLayer = Layers.Player 고정 → 상태 전이 중 레이어가 달라지면 복구 레이어가 틀림.
수정: origLayer = gameObject.layer (호출 시점 실제 레이어)로 변경 + 이미 무적 레이어인 경우 중복 진입 방어.
PlayerParryController2D.cs — 패리 버퍼 한도문제: _overlapBuffer 크기 8 → 밀집 구간에서 콜라이더 8개 초과 시 대상 누락.
수정: 버퍼 크기 16으로 확장.
BlinkState.cs — 재개 입력 억제 게이트 누락문제: 패리(PlayerParryController2D)는 IsResumeInputSuppressActive를 체크하는데, Shift 블링크(BlinkState)는 미적용 → 재개 직후 블링크가 뚫릴 수 있음.
수정: Tick()에 IsResumeInputSuppressActive 게이트 추가.
GameInitializer.cs + ChapterStoryLoader.cs — 중복 switch 제거문제: 동일한 StoryKey → List<CutsceneLine> 분기가 두 파일에 복제 → 한쪽만 수정 시 불일치.
수정: Assets/Dialogue/StoryLineLoader.cs (신규 static 클래스)로 단일화. 두 파일 모두 StoryLineLoader.Load(key)로 위임.
PrepareStoryUiForResume은 _fadeOverlay(로컬)만 클리어. FadeManager가 별도 전용 오버레이를 쓰면 Resume 후에도 검정 화면 남음.| 이슈 | 파일 | 내용 |
|---|---|---|
walkOnlyNoJump 공중 속도 미리셋 |
PlayerMovement2D.cs |
트리거 직전 공중에 있으면 의도치 않은 이동 가능 |
SlamState 직접 타입 체크 |
PlayerMovement2D.cs |
새 "이동 막는 상태" 추가 시 매번 분기 수동 추가 필요 |
_playerMovement null Raw 폴백 |
PlayerStateMachine.cs |
GetMovementHorizontalAxis에서 컷신 가상 입력 미반영 |
| 데드존 상수 중복 | IdleState.cs / RunState.cs |
inputDeadZone 두 곳 — 한쪽만 바뀌면 애니·이동 불일치 |
| 인스펙터 라인 무조건 덮어씀 | ChapterStoryLoader.cs |
Awake에서 수동 입력 라인 덮어쓰기 — 디버그 어려움 |
| 공중 블링크 제한 주석 처리 | PlayerBlinkController2D.cs |
maxAirBlinkCount 변수는 있으나 실제 제한 로직 비활성 — 기획·코드 불일치 |
| 이슈 | 파일 | 내용 |
|---|---|---|
| FixedUpdate 물리 쿼리 과다 | PlayerMovement2D.cs |
BoxCast + 보조 레이 2개 + 벽 프로브 레이 6개 |
| 블링크마다 GameObject 동적 생성 | PlayerBlinkController2D.cs |
LineRenderer 등 매 블링크마다 생성·파괴 → 풀링 권장 |
| 미사용 메서드 | PlayerBlinkController2D.cs |
PlayBlinkSoundSafe 호출처 없음 — 삭제 가능 |
ForceMeshUpdate(true) 과호출 |
CutscenePlayer.cs |
라인마다 호출 — 불필요한 경우도 포함 |
Assets/Dialogue/StoryLineLoader.csStoryKey → List<CutsceneLine> 단일 로드 진입점.
ChapterStoryLoader, GameInitializer 공용 — 중복 switch 완전 제거.
| 영역 | 경로 |
|---|---|
| 컷신 재생기 | Assets/Ending/CutscenePlayer.cs |
| 스토리 트리거 | Assets/Story/StoryEventTrigger.cs |
| JSON 로더 | Assets/Dialogue/StoryJsonManager.cs |
| 공통 라인 로더 (신규) | Assets/Dialogue/StoryLineLoader.cs |
| 플레이어 이동 | Assets/Player/PlayerMovement2D.cs |
| 블링크 컨트롤러 | Assets/Player/PlayerBlinkController2D.cs |
| 패리 컨트롤러 | Assets/Player/PlayerParryController2D.cs |
| FSM 블링크 상태 | Assets/Player/States/BlinkState.cs |