fix(studio): многочастные киты в папку + стартовая площадка задаёт спавн
- Кит из нескольких частей (сундук = тело+крышка) теперь кладётся в общую папку (folderManager.createFolder + assignToFolder), выделяется как группа. Раньше части лежали отдельно в корне. - Кит «Стартовая площадка»: on-target скрипт телепортирует игрока НА площадку в начале игры (game.player.teleport через game.after 0.1с). Теперь игрок появляется на ней, а не в фолбэк-точке (0,0). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
4c8f8c99cb
commit
8b887e866a
@ -786,8 +786,9 @@ const KubikonEditor = () => {
|
|||||||
if (cam && fwd) { px = cam.position.x + fwd.x * 6; pz = cam.position.z + fwd.z * 6; }
|
if (cam && fwd) { px = cam.position.x + fwd.x * 6; pz = cam.position.z + fwd.z * 6; }
|
||||||
} catch (e) { /* ignore */ }
|
} catch (e) { /* ignore */ }
|
||||||
|
|
||||||
// 1) Создаём примитивы кита. Запоминаем id первого — для on-target скрипта.
|
// 1) Создаём примитивы кита. Запоминаем все id (первый — для on-target скрипта).
|
||||||
let firstPrimId = null;
|
let firstPrimId = null;
|
||||||
|
const createdIds = [];
|
||||||
if (Array.isArray(kit.prims)) {
|
if (Array.isArray(kit.prims)) {
|
||||||
for (const p of kit.prims) {
|
for (const p of kit.prims) {
|
||||||
const newId = s.primitiveManager?.addInstance(p.type || 'cube', {
|
const newId = s.primitiveManager?.addInstance(p.type || 'cube', {
|
||||||
@ -797,7 +798,19 @@ const KubikonEditor = () => {
|
|||||||
canCollide: p.canCollide !== false, visible: true, anchored: true,
|
canCollide: p.canCollide !== false, visible: true, anchored: true,
|
||||||
name: p.name,
|
name: p.name,
|
||||||
});
|
});
|
||||||
if (firstPrimId == null && newId != null) firstPrimId = newId;
|
if (newId != null) {
|
||||||
|
createdIds.push(newId);
|
||||||
|
if (firstPrimId == null) firstPrimId = newId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Если кит состоит из НЕСКОЛЬКИХ частей — кладём их в общую папку
|
||||||
|
// (объекты из нескольких частей всегда сгруппированы).
|
||||||
|
let kitFolderId = null;
|
||||||
|
if (createdIds.length > 1 && s.folderManager) {
|
||||||
|
kitFolderId = s.folderManager.createFolder(kit.name);
|
||||||
|
for (const pid of createdIds) {
|
||||||
|
s.folderManager.assignToFolder('primitive', pid, kitFolderId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -817,14 +830,18 @@ const KubikonEditor = () => {
|
|||||||
|
|
||||||
markDirty();
|
markDirty();
|
||||||
setScriptsList(s.getScripts?.() || []);
|
setScriptsList(s.getScripts?.() || []);
|
||||||
// Выделим созданный объект и наведём на него камеру (видно, куда добавилось).
|
if (s.folderManager) setFoldersList(s.folderManager.getAll());
|
||||||
if (firstPrimId != null) {
|
// Выделим созданное и наведём камеру (видно, куда добавилось).
|
||||||
try {
|
try {
|
||||||
setActiveTool('select');
|
setActiveTool('select');
|
||||||
|
if (kitFolderId != null) {
|
||||||
|
s.selection?.selectFolder?.(kitFolderId); // группа из нескольких частей
|
||||||
|
setGizmoMode('move');
|
||||||
|
} else if (firstPrimId != null) {
|
||||||
s.selection?.selectPrimitiveById(firstPrimId);
|
s.selection?.selectPrimitiveById(firstPrimId);
|
||||||
s.focusOnSelection?.();
|
}
|
||||||
} catch (e) {}
|
s.focusOnSelection?.();
|
||||||
}
|
} catch (e) {}
|
||||||
// Тост-уведомление.
|
// Тост-уведомление.
|
||||||
try { showToast?.(`Механика «${kit.name}» добавлена`); } catch (e) {}
|
try { showToast?.(`Механика «${kit.name}» добавлена`); } catch (e) {}
|
||||||
}, []);
|
}, []);
|
||||||
|
|||||||
@ -75,9 +75,16 @@ game.onMessage('coins', (m) => { coins += (m && m.add) ? m.add : 1; show(); });`
|
|||||||
{
|
{
|
||||||
id: 'start-pad',
|
id: 'start-pad',
|
||||||
name: 'Стартовая площадка',
|
name: 'Стартовая площадка',
|
||||||
desc: 'Светящаяся платформа-постамент для оформления зоны старта (точка спавна в проекте уже есть по умолчанию).',
|
desc: 'Светящаяся платформа — игрок появляется НА ней в начале игры (задаёт точку старта).',
|
||||||
icon: 'flag', category: 'world',
|
icon: 'flag', category: 'world',
|
||||||
prims: [{ type: 'cylinder', x: 0, y: 0.15, z: 0, sx: 3, sy: 0.3, sz: 3, color: '#36d57a', material: 'neon', name: 'Стартовая площадка' }],
|
prims: [{ type: 'cylinder', x: 0, y: 0.15, z: 0, sx: 3, sy: 0.3, sz: 3, color: '#36d57a', material: 'neon', name: 'Стартовая площадка' }],
|
||||||
|
scripts: [{ attachTo: 'on-target', code:
|
||||||
|
`// Игрок появляется на этой площадке в начале игры.
|
||||||
|
// Небольшая задержка — чтобы позиция объекта и игрок успели проинициализироваться.
|
||||||
|
game.after(0.1, () => {
|
||||||
|
const p = game.self.position;
|
||||||
|
game.player.teleport(p.x, p.y + 1.5, p.z);
|
||||||
|
});` }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'checkpoint',
|
id: 'checkpoint',
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user