91 lines
11 KiB
Markdown
91 lines
11 KiB
Markdown
---
|
||
phase: research
|
||
agent: research-advisor
|
||
agent_version: 4
|
||
report_invocation_id: inv-001
|
||
concerns_checked: true
|
||
source_confidence: mixed
|
||
workers_spawned: 0
|
||
concerns:
|
||
- Unity 씬 소스 미포함으로 실제 UI anchor/Canvas Scaler 설정 확인 불가
|
||
- 브라우저 실행 전이므로 화면 잘림 및 입력 이상은 아직 런타임 확인하지 않음
|
||
- 분리 asset origin 사용 시 부모의 iframe DOM 직접 접근 불가
|
||
---
|
||
|
||
# WebGL 해상도 대응 조사
|
||
|
||
## 결론
|
||
|
||
원인 후보는 플랫폼의 고정 가로 플레이 영역과 빌드 HTML의 세로 영역 계산이다. “Unity가 390×844 해상도만 렌더한다”는 가정은 자료와 맞지 않는다. 이 ZIP은 이미 CSS 크기에 맞춰 Unity 렌더 타깃을 동기화하는 설정이며, 게임 내부 UI가 새 크기에 맞춰 배치되는지는 별개의 문제다.
|
||
|
||
기본 정책은 **원본 390:844 비율을 유지하면서 가능한 영역 안에 전체 화면을 표시(contain)**하는 것을 추천한다. README가 PC에서도 세로 화면 유지한다고 명시하므로 화면을 늘리거나 자르는 cover/fill 정책은 이 게임의 안전한 기본값이 아니다. 여백 없이 모든 화면을 채우려면 Unity 소스에서 다양한 비율의 UI와 카메라를 검증·수정하여 재빌드해야 한다.
|
||
|
||
## ZIP 근거 (원본 변경 없음)
|
||
|
||
ZIP: `/Users/wemadeplay/Downloads/GoraniCoin-WebGLTest.zip`; zipfile로 읽기만 수행.
|
||
|
||
- `GoraniCoin-WebGLTest/build-info.json:5`: Unity `6000.0.74f1`.
|
||
- `build-info.json:8,13–14`: `Assets/Scenes/UITestScene_Final.unity`, 기준 `390×844`.
|
||
- `README.txt:3`: PC에서도 세로 화면 유지. `README.txt:5`: Toss 결제 및 호스트 safe-area 호출 비활성화. 실제 프로젝트 소스는 ZIP에 없다.
|
||
- `index.html:9–15`: html/body 100%, overflow hidden; container 폭 `min(100vw, calc(100svh * 390 / 844))`, 높이 `100svh`; canvas CSS 폭/높이 100%.
|
||
- `index.html:27`: canvas 초기 HTML 버퍼 속성 390×844. 이 속성만으로 실행 중 렌더 타깃이 고정이라고 판단하면 안 된다.
|
||
- `index.html:46–61`: config에 `devicePixelRatio: Math.min(window.devicePixelRatio || 1, 2)` 설정. `matchWebGLToCanvasSize`는 미설정.
|
||
- `Build/GoraniCoin-WebGLTest.framework.js:7575–7580`: `matchWebGLToCanvasSize`가 undefined면 true를 반환. `:7592–7594`: preferred DPR은 match false면 1, 그 외 Module DPR/window DPR 사용.
|
||
- `index.html:69–71`: `window.unityInstance`, 준비 상태 `data-unity-ready`를 제공하여 브라우저 검사에 활용 가능.
|
||
|
||
**HTML의 비율 결함:** 컨테이너 폭이 viewport 폭 때문에 제한되더라도 높이는 viewport 전체 높이를 유지한다. 예를 들어 iframe 320×844라면 canvas CSS가 320×844가 되어 원래 390:844보다 좁다. Unity는 이 비율에서 새 렌더링을 할 가능성이 높으며, UI가 잘리는지 여부는 내부 레이아웃에 달렸다. 적절한 contain 계산은 `scale=min(availableWidth/390, availableHeight/844)`, 폭 `390*scale`, 높이 `844*scale`이다. 이미지 CSS stretch와 Unity UI 재배치를 혼동하지 않아야 한다.
|
||
|
||
## 플랫폼 근거
|
||
|
||
- `src/main/webapp/WEB-INF/views/game-detail.jsp:365–384`: frame wrap 폭 100%, `aspect-ratio:16/9`, `max-height:min(70vh,520px)`, overflow hidden; iframe absolute inset 0, 폭/높이 100%. 비율과 최대 높이가 동시에 걸려 실제 frame 비율이 16:9보다 넓어질 수도 있다.
|
||
- `game-detail.jsp:1259–1264`: 업로드 빌드 URL iframe에 그대로 연결. sandbox scripts/same-origin/pointer-lock 허용; fullscreen/autoplay 권한 허용. 전체화면 제어 UI는 없음.
|
||
- 이 빌드가 800×450 iframe에 들어가면 자체 portrait 계산에 의해 canvas 약 208×450이 되어 큰 좌우 여백과 작은 세로 화면이 생긴다. 모바일 상세 페이지의 가로 iframe은 더 낮아질 수 있다. 이는 계산상 예상이며 아직 실화면 재현은 아니다.
|
||
- `src/main/java/com/pandoli365/bibimbap/controller/api/GameUploadController.java:198–225`: ZIP 압축 해제, index 탐색, Unity 파일 검증, 디렉터리 이동, 빌드 index URL 반환. 별도 템플릿 정규화나 responsive wrapper는 없다.
|
||
- `src/main/java/com/pandoli365/bibimbap/controller/api/GameAssetController.java:57–68`: CSP 헤더 설정 뒤 파일 바이트 그대로 복사. CSP는 self/inline script와 self/inline style을 허용한다. CSP 변경 자체는 해상도 지원에 필요하지 않다.
|
||
- `src/main/java/com/pandoli365/bibimbap/controller/api/GameController.java:348–357`: `app.webgl.asset-origin`이 있으면 iframe을 별도 origin에 연결. 따라서 “부모 페이지 JS가 모든 게임의 canvas를 직접 고친다”는 구현은 일반화 불가. 호스트는 iframe 박스 크기는 변경 가능하나 내부 문서는 same-origin에서만 직접 접근 가능하다.
|
||
- `src/main/java/com/pandoli365/bibimbap/data/GameData.java` 및 game-register 입력에 게임 해상도/비율 메타 필드는 발견되지 않았다.
|
||
- `docs/graph/index.md` 알려진 한계와 `docs/development/verification-strategies.md:260–262`: JSP/CSS 정적 프론트 코드는 직접 탐색 대상. graph lookup skip은 타당.
|
||
- contracts index는 아직 비어 있고 해상도 계약 문서는 없음. usage index 일부 링크는 파일이 존재하지 않아 해당 문서에 의존하지 않음.
|
||
|
||
## 외부 근거 — Unity 공식 문서 확인
|
||
|
||
[Unity 6.0 Web Canvas size](https://docs.unity3d.com/6000.0/Documentation/Manual/webgl-canvas-size.html): CSS 표시 크기와 GPU 렌더 타깃을 구분하며 기본 자동 동기화를 설명한다. `matchWebGLToCanvasSize=false`는 자동 동기화를 끄고 버퍼를 수동 관리할 때 사용하는 설정이다. 이 게임의 config와 framework 근거가 기본 동기화와 일치한다.
|
||
|
||
[Unity uGUI 2.0 Canvas Scaler](https://docs.unity3d.com/Packages/com.unity.ugui@2.0/manual/script-CanvasScaler.html): Scale With Screen Size/Reference Resolution/Screen Match Mode가 UI 크기와 서로 다른 비율의 레이아웃을 결정한다. HTML에서 렌더 해상도를 바꾸는 것만으로 게임 내부 레이아웃 적응을 보장할 수 없다. 현재 게임이 uGUI인지 UI Toolkit인지도 ZIP만으로 확정하지 않는다.
|
||
|
||
[MDN postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage): 다른 origin의 iframe과 통신하려면 협력하는 child 측 프로토콜이 필요하며 sender origin/source와 message 값을 검증해야 한다. 부모에서 iframe src만 넣는 현행 구조로는 임의 ZIP의 내부 비율 자동 감지/수정 계약이 없다.
|
||
|
||
## 권장 구현 계획 (구현하지 않음)
|
||
|
||
1. 빌드 원본과 플레이어를 로컬 HTTP로 실행해 기준 390×844 화면, 창 축소, 모바일 세로·가로에서 재현한다. 준비 상태/실제 canvas client size와 width·height를 기록한다.
|
||
2. bibimbap 플레이 영역에 사용자 조절 가능한 비율(현재 가로/세로/원본 또는 사용자 지정)과 확대/전체화면 기능을 도입한다. 390:844 같은 정확 비율을 유지하면서 부모 가용 폭과 높이 양쪽에 맞게 계산한다. 앱의 iframe 전체를 390:844로 맞추면 이 ZIP의 자체 CSS를 수정하지 않고도 양쪽 계산이 일치하게 만들 수 있다. “세로”를 일반 9:16으로만 맞추면 이 게임 원본과 다르므로 원본 정확 비율 옵션이 필요하다.
|
||
3. 최소 변경안은 상세 JSP/CSS/전용 JS와 플레이어 테스트를 수정하고, 기존 게임은 현재 정책으로 fallback하면서 이번 게임은 사용자가 원본 비율을 선택할 수 있도록 한다. 화면 비율 추론을 hardcode하거나 특정 ZIP 이름을 앱에 박지 않는다.
|
||
4. 모든 게임에 자동 대응이 필요하면 작성자 해상도/비율 메타 입력 또는 협력하는 표준 빌드 메타/resize message 계약을 추가한다. 메타 저장은 GameData/Mapper/API/등록 JSP/DB migration 및 계약 테스트로 영향이 커진다. 업로드 HTML 임의 주입/정규식 개조는 범용 보장과 원본 보존 측면에서 우선안으로 추천하지 않는다.
|
||
5. 이 게임 HTML 자체도 개선하려면 원본 ZIP을 보존하고 복사본 index 컨테이너만 양축 contain 방식으로 보정한다. 재빌드 없이 가능한 웹 wrapper 수정이지만, 내부 UI 재설계와는 다르다. matchWebGLToCanvasSize=false나 고정 버퍼는 픽셀 기준 UI 문제가 실제 확인됐을 때 개발자와 함께 검토한다.
|
||
|
||
## 영향 파일 후보
|
||
|
||
최소 플랫폼안: `src/main/webapp/WEB-INF/views/game-detail.jsp`, 신규 전용 WebGL player JS/CSS, 동작 회귀 테스트, `docs/changes/...`, 해상도 사용 계약 문서. 공용 `.player` CSS(`bibimbap.css:343`)는 현재 상세 페이지 실제 iframe class와 다르므로 그 줄만 바꾸어도 해결되지 않는다.
|
||
|
||
자동 메타 영속화안: 위 + `GameData.java`, `GamesMapper.java`, `GameController.java`, 등록 폼, upload metadata parser(채택 시), DB migration, 컨트롤러/매퍼 테스트. 이는 이번 조사에서 확정한 구현 요구사항이 아니라 별도 범위 선택이다.
|
||
|
||
## 검증 기준
|
||
|
||
- 원본 390:844와 좁은 320×844, desktop 1440×900, 가로 844×390, 작은 높이 창에서 플레이 영역 양축이 가용 공간을 넘지 않음.
|
||
- contain 모드 canvas/iframe 비율 390:844, 화면 잘림 없이 중앙 정렬. 여백은 의도대로 남음. ResizeObserver/viewport resize 후 갱신되고 Unity instance가 재생성되지 않아 플레이 상태가 유지됨.
|
||
- Unity 준비 후 CSS 크기와 drawing buffer 크기를 각각 기록; DPR 1/2에서 실제 동기화를 확인. initial width/height attribute만 검사하지 않음.
|
||
- 게임 로딩/상하단 UI/버튼 클릭/터치/포인터 위치/다시 축소/전체화면 진입과 해제를 실제 빌드로 확인. 화면만 보기 좋은데 입력이 틀어지는 회귀를 방지.
|
||
- 기존 가로 게임과 별도 asset-origin 구성에서 iframe 재생이 유지됨. cross-origin 접근 실패를 정상 지원 여부와 구분.
|
||
- `docs/development/verification-strategies.md`에 따라 수정 전 실패→수정 후 통과하는 회귀 포함, JSP 변경은 WAR 빌드 외 HTTP 200 런타임 스모크가 의무.
|
||
|
||
## 미해결
|
||
|
||
- 사용자가 원하는 대응 범위: 원본 콘텐츠를 전체 표시하며 확대하는 플레이어인가, 게임 UI가 가로·세로 전체 화면에서 재배치되는 것인가? 후자는 Unity 소스 또는 담당 개발자의 재빌드가 필요할 수 있다.
|
||
- 각 게임 비율의 자동 감지/저장까지 이번 범위인지 여부.
|
||
- 실제 Unity UI 컴포넌트와 픽셀 단위 레이아웃, 카메라 viewport, safe-area 대응 설정.
|
||
- 현행 플레이어와 ZIP의 런타임 실화면은 아직 미실행.
|
||
|
||
## 실행 계약
|
||
|
||
Parent instruction에 따라 nested children 0건. update_plan은 callable tools에 없어 bind 호출을 만들지 않았으며 parent에 명시 고지했다. 제품 코드/원본 ZIP/credential 미변경. 파일 산출은 이 research.md 1건만이다.
|