Files
onboarding-project/docs/worklog/05-camera-facing-lock.md
T
2026-08-14 15:03:43 +03:00

36 lines
3.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Камера підлаштовується під facing-lock на крейт (2026-08-12)
Користувач: коли персонаж зупиняється біля ящика і "тригер збору"
(`PlayerC.faceTowards`, викликається з `updateMovement` коли `stopped &&
nearbyObstacle`) розвертає його лицем до цілі, камера має підлаштовуватись
під новий кут, а не лишатись байдужою. Це саме той кейс, який попередній
рух-based `lookAhead` **свідомо** ігнорував (розворот на місці = нульовий
`movement` = look-ahead не оновлюється) — правильна поведінка для
довільного розвороту, але користувач хотів виключення саме для facing-lock
на breakable-ціль.
**Рішення без повернення до facing/quaternion-залежності** (яка й дала
"рух по колу" раніше): `PlayerC` тепер зберігає, на яку саме ТОЧКУ (не
кут!) він зараз locked — `facingTarget: Vector3 | null`, виставляється в
`updateMovement()` в той самий момент, коли викликається `faceTowards()`
(і скидається в `null`, коли умова `stopped && nearbyObstacle` неправдива).
Публічний `PlayerC.getFacingTarget()`.
`CameraFollowC.setFacingTargetGetter(getter)` — injected getter (той самий
DI-паттерн, що й `ResourceC.setFlyTarget`), підключено в `TestSceneC.init()`
відразу після `CameraFollowC.init()`. В `update()`: якщо `facingTarget` не
`null` — `desiredLookAhead` рахується як напрямок від гравця ДО цієї точки
(XZ, нормалізований) × `LOOK_AHEAD_DISTANCE`, замість напрямку руху; інакше
— стара логіка (рух або hold). Ключове: джерело — фіксована ТОЧКА в
world-space (`nearbyObstacle.center`), а не обертовий вектор — поки гравець
і ящик обидва стоять на місці, цей напрямок сам по собі константний, тож
`smoothedLookAhead.lerp(...)` дає один плавний лінійний зсув до нової
позиції й ЗУПИНЯЄТЬСЯ там, а не описує дугу (на відміну від
facing/quaternion-based версії, яка оберталась разом з тілом персонажа).
Перевірено (Playwright, тимчасове логування `window.__dbgFacing`/
`__dbgLookAhead`, видалене після): після зупинки біля крейта
`facingTarget` стає non-null, і `smoothedLookAhead` плавно зсувається від
~`(-0.02, 1.46)` до нового значення (`(-1.03, 1.08)` і триває сходитись) —
камера реально підлаштовується, а не стоїть на місці.