fix(g20): отложенный setLabel для NPC до npcSpawned-резолва

setLabel сразу после spawnNpc возвращал null от _resolveTweenTarget
(маппинг localRef→realId ещё не записан). Метки молча терялись.

Фикс: если ref начинается с npc_lua_ — откладываем через _npcCmd
(re-вызов после npcSpawned). Иначе retry через 0.3с.
This commit is contained in:
min 2026-06-09 20:41:09 +03:00
parent b83c9bb75c
commit 1be06343ec

View File

@ -3615,17 +3615,29 @@ export class GameRuntime {
const ref = payload?.ref; const ref = payload?.ref;
const text = payload?.text; const text = payload?.text;
if (typeof ref !== 'string') return; if (typeof ref !== 'string') return;
// ленивое создание менеджера меток
if (!this.scene3d._labelManager) { if (!this.scene3d._labelManager) {
this.scene3d._labelManager = new LabelManager(this.scene3d.scene); this.scene3d._labelManager = new LabelManager(this.scene3d.scene);
} }
const lm = this.scene3d._labelManager; const lm = this.scene3d._labelManager;
// резолвим меш объекта (примитив или модель) const applyLabel = () => {
const tgt = this._resolveTweenTarget(ref); const tgt = this._resolveTweenTarget(ref);
const mesh = tgt && (tgt.data.mesh || tgt.data.rootMesh || tgt.data.rootNode); const mesh = tgt && (tgt.data.mesh || tgt.data.rootMesh || tgt.data.rootNode);
if (mesh) { if (mesh) {
lm.setLabel(ref, mesh, text, payload?.opts || {}); lm.setLabel(ref, mesh, text, payload?.opts || {});
} }
};
// Если NPC ещё не зарезолвлен — откладываем через _npcCmd
// (или просто несколько попыток с retry).
const tgt = this._resolveTweenTarget(ref);
if (tgt) {
applyLabel();
} else if (typeof ref === 'string' && ref.startsWith('npc_lua_')) {
// NPC ещё спавнится — откладываем
this._npcCmd(ref, () => applyLabel());
} else {
// Retry через 0.3с (для primitive после sceneCreate)
setTimeout(applyLabel, 300);
}
} catch (e) { } catch (e) {
console.warn('[GameRuntime] scene.setLabel failed', e); console.warn('[GameRuntime] scene.setLabel failed', e);
} }