Utility and polishing + bag fixes
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
# Камера з конфігу платформи стала реальною (2026-08-14)
|
||||
|
||||
Слайдери `camera_position_p/_l` і `camera_rotation_p/_l` у Scene settings були
|
||||
мертві: `CameraFollowC.init()` рахував позицію з константи `CAMERA_OFFSET` і
|
||||
виводив кут одноразовим `lookAt()`, а конфіг не читав узагалі. Продюсер міг
|
||||
крутити шість повзунків без жодного ефекту.
|
||||
|
||||
Вимога: повзунки прибирати не можна, вони мають працювати — і в експорті, і в
|
||||
прев'ю платформи.
|
||||
|
||||
## Що з'ясувалось під час розбору
|
||||
|
||||
**Формат конфігу читається не так, як виглядає.** У `globalSettings.ts` кожна
|
||||
вісь масивного параметра описана як `[min, max, default]`, тому
|
||||
`camera_position_p` виглядав як три трійки координат. Насправді дефолт — це
|
||||
третій елемент кожної трійки, а в рантаймі `Template.getCategory("global")`
|
||||
віддає плаский `[x, y, z]`. Перевірено прогоном справжнього
|
||||
`formConfigForPlayable(formConfigUI(...))` над нашим же `globalSettings`.
|
||||
|
||||
**Старі дефолти були з іншої моделі камери.** `[-2, 5, 42]` — це абсолютна
|
||||
позиція камери зі статичного SDK-шаблону. У грі з follow-камерою абсолютна
|
||||
позиція безглузда (її перезаписує кожен кадр), осмислений лише офсет відносно
|
||||
гравця. Оскільки ці значення ніколи ні на що не впливали, від них нічого не
|
||||
залежало — семантику переінтерпретовано на офсет.
|
||||
|
||||
**`Object3D.lookAt` і `Camera.lookAt` — різні.** Перша спроба вирахувати
|
||||
еквівалентний кут дала `x=53.13, y=0, z=0` і виглядала правдоподібно, але
|
||||
контрольна перевірка (зібрати кватерніон назад із цих кутів і зміряти
|
||||
`forward · напрямок_на_ціль`) дала **−1.0** — камера дивилась рівно в
|
||||
протилежний бік. Причина в самому three.js:
|
||||
|
||||
```js
|
||||
if (this.isCamera || this.isLight) _m1.lookAt(_position, _target, this.up);
|
||||
else _m1.lookAt(_target, _position, this.up);
|
||||
```
|
||||
|
||||
Звичайний `Object3D` наводить на ціль свою вісь **+Z**, камера — **−Z**. Розрахунок
|
||||
на `Object3D` замість `PerspectiveCamera` дає дзеркальний результат.
|
||||
**Урок**: будь-який офлайн-розрахунок орієнтації перевіряти зворотним ходом
|
||||
(відновити з чисел і зміряти скалярний добуток), а не приймати правдоподібні
|
||||
числа на віру.
|
||||
|
||||
Справжній кут для офсету `(0, 8, -6)` — `x=-126.87, y=0, z=-180`. Еквівалентна,
|
||||
але читабельніша форма `x=53.13, y=180, z=0` дає той самий кватерніон і той
|
||||
самий up-вектор — саме її записано в дефолти. `y=180` тут не довільне: риг стоїть
|
||||
позаду гравця на −Z і дивиться назад у +Z, а камера three.js за замовчуванням
|
||||
дивиться в −Z.
|
||||
|
||||
Тип параметра — `int`, тож `53.13` округлено до `53`. Відхилення від старого
|
||||
кадру — **0.13°**, візуально непомітно.
|
||||
|
||||
## Що змінено
|
||||
|
||||
- `globalSettings.ts` — тільки дефолти (id, назви, типи й діапазони не чіпані;
|
||||
діапазони вже покривали нові значення). Портрет і ландшафт отримали однаковий
|
||||
риг, бо гра й досі використовує один `CAMERA_OFFSET` для обох — тепер їх можна
|
||||
розвести з платформи.
|
||||
- `CameraFollowC` — новий `applyRigFromConfig()`: читає офсет і кут за поточною
|
||||
орієнтацією, застосовує кут, лишається єдиним писарем `camera.rotation`.
|
||||
`readVec3()` відсіює биті значення, і тоді кут виводиться старим способом
|
||||
(`frameTargetAndStoreRotation()`) — зламаний конфіг деградує до «кадрує
|
||||
гравця», а не до порожнього неба.
|
||||
- `beforeResourcesLoadedCb` — `updateVariableConfig` тепер маршрутизує
|
||||
`camera_position_*`/`camera_rotation_*` у `CameraFollowC`, FOV лишається за
|
||||
`CameraC`. Роздільна власність — це і є захист від повторення бага з двома
|
||||
писарями.
|
||||
- `resizeCb` — на зміні орієнтації перечитує і FOV, і риг.
|
||||
- `DebugConfigC` — повзунки кута/дистанції сідають із того самого конфігу
|
||||
(`readCameraRigFromConfig()`), дубльована константа `DEFAULT_CAMERA_OFFSET`
|
||||
прибрана. `setOffset()` і далі авто-кадрує й синхронізує `rotationDeg`.
|
||||
- `TestSceneC.CAMERA_OFFSET` — лишився як фолбек, коментар оновлено.
|
||||
|
||||
## Перевірено
|
||||
|
||||
- `npx vite build` — 886 модулів, чисто.
|
||||
- Прогін реального SDK-пайплайна: гра читає `camera_position_p = [0, 8, -6]`,
|
||||
`camera_rotation_p = [53, 180, 0]`; відновлена з цих чисел камера дивиться на
|
||||
гравця з похибкою 0.13°.
|
||||
- `npx tsc --noEmit` у проєкті **не запускається** — `tsconfig.json` містить
|
||||
`moduleResolution: node10`, яку TypeScript 7 видалив (TS5108). З обходом цієї
|
||||
опції лишаються дві доіснуючі помилки, обидві не в зміненому коді:
|
||||
deep-import `three/src/math/Color` у `ThreeC.ts` і застаріла декларація SDK для
|
||||
`JoystickC.init({ color })`.
|
||||
|
||||
## Не перевірено
|
||||
|
||||
Візуально в браузері нічого не запускалось. Потрібен ручний прогін: старт у
|
||||
портреті, поворот у ландшафт, правка повзунків на платформі наживо.
|
||||
|
||||
## Відкрите
|
||||
|
||||
Значення, збережені для вже наявних креативів на платформі, лишились у старій
|
||||
(абсолютній) семантиці — їх треба одноразово перевиставити на офсет-значення.
|
||||
Reference in New Issue
Block a user