fix(studio): F-фокус на выделенном объекте, автофокус при вставке кита, двойной прыжок

- F в редакторе теперь фокусирует камеру на ВЫДЕЛЕННОМ объекте (раньше всегда
  летел в центр 0,0,0). Если выделения нет — центр сцены. Только в edit-режиме.
- focusOnSelection поддерживает userModel + запасной путь по позиции меша.
- Вставка кита из Тулбокса: объект выделяется И камера наводится на него
  (видно, куда добавилось) + переключение на инструмент «Выделить».
- Кит «Двойной прыжок» чинён: был setJumpPower (высокий прыжок) →
  game.player.setDoubleJump(true) (настоящий второй прыжок в воздухе по Space).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
min 2026-06-05 01:45:40 +03:00
parent b774f92d40
commit 4284fef704
3 changed files with 26 additions and 10 deletions

View File

@ -814,8 +814,14 @@ const KubikonEditor = () => {
markDirty();
setScriptsList(s.getScripts?.() || []);
// Выделим созданный объект (если был) для наглядности.
if (firstPrimId != null) { try { s.selection?.selectPrimitiveById(firstPrimId); } catch (e) {} }
// Выделим созданный объект и наведём на него камеру (видно, куда добавилось).
if (firstPrimId != null) {
try {
setActiveTool('select');
s.selection?.selectPrimitiveById(firstPrimId);
s.focusOnSelection?.();
} catch (e) {}
}
// Тост-уведомление.
try { showToast?.(`Механика «${kit.name}» добавлена`); } catch (e) {}
}, []);

View File

@ -2556,8 +2556,13 @@ export class BabylonScene {
if (e.code === 'KeyR') { e.preventDefault(); this.placementManager.rotate(); return; }
if (e.code === 'Escape') { e.preventDefault(); this.placementManager.cancel(); return; }
}
if (e.code === 'KeyF') {
this._focusOnTarget(new Vector3(0, 0, 0));
if (e.code === 'KeyF' && !this._isPlaying) {
// F — фокус камеры на выделенном объекте (если есть), иначе центр сцены.
if (this.selection?.getSelection()) {
this.focusOnSelection();
} else {
this._focusOnTarget(new Vector3(0, 0, 0));
}
}
// Ctrl+D — дублировать выделенное
if (e.code === 'KeyD' && (e.ctrlKey || e.metaKey) && !this._isPlaying) {
@ -5721,9 +5726,14 @@ export class BabylonScene {
let target;
if (sel.type === 'block') {
target = new Vector3(sel.gridX, sel.gridY + 0.5, sel.gridZ);
} else if (sel.type === 'model' || sel.type === 'spawn' || sel.type === 'primitive') {
} else if (sel.type === 'model' || sel.type === 'spawn' || sel.type === 'primitive' || sel.type === 'userModel') {
target = new Vector3(sel.x, sel.y + 0.5, sel.z);
}
// Запасной путь: взять позицию из меша выделения (userModel/модель без x,y,z).
if (!target) {
const root = this._getSelectionRoot?.(sel);
if (root?.position) target = new Vector3(root.position.x, root.position.y + 0.5, root.position.z);
}
if (target) this._focusOnTarget(target);
}

View File

@ -36,13 +36,13 @@ game.onKeyUp('shift', () => game.player.setSpeed(1.0));` }],
{
id: 'double-jump',
name: 'Двойной прыжок',
desc: 'Разрешает второй прыжок в воздухе. Подсказка появляется при старте.',
desc: 'Разрешает второй прыжок прямо в воздухе. Нажми Space ещё раз во время прыжка.',
icon: 'arrow-up', category: 'movement',
scripts: [{ attachTo: 'global', code:
`// Двойной прыжок (упрощённо — повышенная высота прыжка)
game.player.setJumpPower && game.player.setJumpPower(1.6);
game.ui.set('dj', 'Прыгай — теперь выше!', { x: 50, y: 90, anchor: 'bottom', color: '#fff', size: 16 });
game.after(4, () => game.ui.set('dj', ''));` }],
`// Двойной прыжок: второй прыжок в воздухе по Space
game.player.setDoubleJump(true);
game.ui.set('dj', 'Двойной прыжок включён! Жми Space в воздухе.', { x: 50, y: 90, anchor: 'bottom', color: '#fff', size: 16 });
game.after(5, () => game.ui.set('dj', ''));` }],
},
{
id: 'day-night-cycle',