fix(player): порядок чтения скина + управление камерой 02 + авто-меню
1. Стартовый скин не ставился: блок чтения scene.skins/playerModelType стоял НИЖЕ предзагрузки модели и enterPlayMode. Перенёс ВЫШЕ — теперь PlayerController при старте видит корректный _playerModelType. 2. Меню открывалось каждые ~4с: onPointerLockChange звал _onExitRequest при любой потере lock. В third/front потеря lock = отпустили ПКМ (orbit), это НЕ выход. Меню (Esc) только из perma-режимов (first/lockfirst/sideview/ shift-lock). 3. Управление 02: start() лочит только в perma-режимах; onCanvasClick не лочит в third (курсор свободен для GUI/3D-табличек); ПКМ-orbit (onRmbDown/Up); onWheel авто-переход third<->first; _isPermaLockMode/_applyCursorVisibility. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6a2aeefee5
commit
85f8198c7c
@ -7154,6 +7154,35 @@ export class BabylonScene {
|
|||||||
this._syncUserModelColliders();
|
this._syncUserModelColliders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// === Тип модели персонажа — РЕШАЕМ ДО предзагрузки/плеера ===
|
||||||
|
// ВАЖНО: должно стоять ВЫШЕ _loadPrototype и до enterPlayMode, иначе
|
||||||
|
// PlayerController прочитает старый _playerModelType (баг: пончик 2046
|
||||||
|
// не ставился — skins.default применялся ниже, после предзагрузки).
|
||||||
|
// Миграция: старые проекты сохраняли Kenney-модель ('character-a..g');
|
||||||
|
// форсим R15 bacon-hair. Явно выбранные 'skin_*' не трогаем.
|
||||||
|
if (state.scene.playerModelType) {
|
||||||
|
const pmt = state.scene.playerModelType;
|
||||||
|
this._playerModelType = pmt.startsWith('character-') ? 'skin_bacon-hair' : pmt;
|
||||||
|
}
|
||||||
|
// Задача 07: конфиг скинов { default, unlocked, shopVisible, coins, customGlbs }.
|
||||||
|
if (state.scene.skins && typeof state.scene.skins === 'object') {
|
||||||
|
this._skinsConfig = {
|
||||||
|
default: state.scene.skins.default || null,
|
||||||
|
unlocked: Array.isArray(state.scene.skins.unlocked) ? state.scene.skins.unlocked.slice() : [],
|
||||||
|
shopVisible: state.scene.skins.shopVisible !== false,
|
||||||
|
coins: Number.isFinite(state.scene.skins.coins) ? state.scene.skins.coins : 0,
|
||||||
|
customGlbs: Array.isArray(state.scene.skins.customGlbs) ? state.scene.skins.customGlbs.slice() : [],
|
||||||
|
};
|
||||||
|
// Стартовый скин из skins.default имеет приоритет над playerModelType.
|
||||||
|
if (this._skinsConfig.default) {
|
||||||
|
const d = this._skinsConfig.default;
|
||||||
|
this._playerModelType = (d.startsWith('character-') || d.startsWith('skin_') || d.startsWith('customskin:'))
|
||||||
|
? d : ('skin_' + d);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this._skinsConfig = null;
|
||||||
|
}
|
||||||
|
|
||||||
// ОПТИМИЗАЦИЯ: предзагружаем модель ИГРОКА (character) тоже —
|
// ОПТИМИЗАЦИЯ: предзагружаем модель ИГРОКА (character) тоже —
|
||||||
// PlayerController.start() её ждёт, но если предзагрузить сейчас,
|
// PlayerController.start() её ждёт, но если предзагрузить сейчас,
|
||||||
// на enterPlayMode она будет в кэше Babylon и стартует мгновенно.
|
// на enterPlayMode она будет в кэше Babylon и стартует мгновенно.
|
||||||
@ -7251,36 +7280,7 @@ export class BabylonScene {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) { console.warn('[BabylonScene] spawn auto-lift failed:', e); }
|
} catch (e) { console.warn('[BabylonScene] spawn auto-lift failed:', e); }
|
||||||
// Тип модели персонажа.
|
// (Тип модели персонажа и skins решены выше — до предзагрузки модели.)
|
||||||
// Миграция: старые проекты сохраняли Kenney-модель ('character-a..g').
|
|
||||||
// Теперь стандарт — R15-скин bacon-hair. Если в проекте старая
|
|
||||||
// Kenney-модель — форсим bacon-hair. Явно выбранные 'skin_*' не трогаем.
|
|
||||||
if (state.scene.playerModelType) {
|
|
||||||
const pmt = state.scene.playerModelType;
|
|
||||||
if (pmt.startsWith('character-')) {
|
|
||||||
this._playerModelType = 'skin_bacon-hair';
|
|
||||||
} else {
|
|
||||||
this._playerModelType = pmt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Задача 07: конфиг скинов проекта { default, unlocked, shopVisible, coins, customGlbs }.
|
|
||||||
if (state.scene.skins && typeof state.scene.skins === 'object') {
|
|
||||||
this._skinsConfig = {
|
|
||||||
default: state.scene.skins.default || null,
|
|
||||||
unlocked: Array.isArray(state.scene.skins.unlocked) ? state.scene.skins.unlocked.slice() : [],
|
|
||||||
shopVisible: state.scene.skins.shopVisible !== false,
|
|
||||||
coins: Number.isFinite(state.scene.skins.coins) ? state.scene.skins.coins : 0,
|
|
||||||
customGlbs: Array.isArray(state.scene.skins.customGlbs) ? state.scene.skins.customGlbs.slice() : [],
|
|
||||||
};
|
|
||||||
// Стартовый скин из skins.default имеет приоритет над playerModelType.
|
|
||||||
if (this._skinsConfig.default) {
|
|
||||||
const d = this._skinsConfig.default;
|
|
||||||
this._playerModelType = d.startsWith('character-') || d.startsWith('skin_') || d.startsWith('customskin:')
|
|
||||||
? d : ('skin_' + d);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this._skinsConfig = null;
|
|
||||||
}
|
|
||||||
// Пользовательские скрипты
|
// Пользовательские скрипты
|
||||||
if (Array.isArray(state.scene.scripts)) {
|
if (Array.isArray(state.scene.scripts)) {
|
||||||
this._scripts = state.scene.scripts
|
this._scripts = state.scene.scripts
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user