diff --git a/src/editor/engine/GameplayKits.js b/src/editor/engine/GameplayKits.js index 915d9c6..8573630 100644 --- a/src/editor/engine/GameplayKits.js +++ b/src/editor/engine/GameplayKits.js @@ -285,18 +285,41 @@ game.self.onTouch(() => { // Скрипт на полотне двери. Филёнки/ручка двигаются вместе как часть полотна? // Нет — они отдельные примитивы, поэтому анимируем только полотно (game.self), // а декор оставляем — на низкой толщине двери смотрится цельно. -const p0 = game.self.position; -const halfW = 1.3; // половина ширины полотна по Z (sz=2.6) -const hingeZ = p0.z - halfW; // петля у левого края +const p0 = game.self.position; // центр полотна (закрытое положение) +const halfW = 1.3; // половина ширины полотна по Z (sz=2.6) +const hingeX = p0.x; +const hingeZ = p0.z - halfW; // петля у левого края let open = false; -let cur = 0, target = 0; // текущий и целевой угол (радианы) -const SPEED = Math.PI; // рад/сек → ~0.5с на 90° +let cur = 0, target = 0; // текущий и целевой угол (радианы) +const SPEED = Math.PI; // рад/сек → ~0.5с на 90° + +// Декор полотна — двигаем вместе с дверью. Запоминаем их СМЕЩЕНИЕ относительно +// центра полотна (в закрытом виде), чтобы вращать вокруг той же петли. +const decorNames = ['Филёнка верх', 'Филёнка низ', 'Ручка']; +const decor = []; +for (const nm of decorNames) { + const o = game.scene.findOne(nm); + if (o && o.position) { + decor.push({ obj: o, dx: o.position.x - p0.x, dy: o.position.y - p0.y, dz: o.position.z - p0.z }); + } +} + function place(angle) { - const cx = p0.x + Math.sin(angle) * halfW; - const cz = hingeZ + Math.cos(angle) * halfW; + const s = Math.sin(angle), c = Math.cos(angle); + // Полотно: его центр на дуге вокруг петли. + const cx = hingeX + s * halfW; + const cz = hingeZ + c * halfW; game.self.move(cx, p0.y, cz); game.self.rotate(angle); + // Декор: позиция центра полотна + повёрнутое локальное смещение. + for (const d of decor) { + const rx = d.dx * c - d.dz * s; // поворот смещения вокруг Y + const rz = d.dx * s + d.dz * c; + d.obj.move(cx + rx, p0.y + d.dy, cz + rz); + if (d.obj.rotate) d.obj.rotate(angle); + } } + // Один постоянный тик плавно ведёт cur → target. game.onTick((dt) => { if (cur === target) return;