'use strict'; /** AppRoot Inspector:SwitchLevel + 游戏调试(对齐 Unity TestPlayer) */ function compUuid(dump) { if (!dump || !dump.value) return ''; const u = dump.value.uuid; return (u && u.value) ? u.value : (typeof u === 'string' ? u : ''); } function nodeUuid(dump) { if (!dump || !dump.value) return ''; const n = dump.value.node; return (n && n.value && n.value.uuid) ? n.value.uuid : ''; } function getMessageProtocolScene(el) { let element = el; while (element) { const root = element.getRootNode && element.getRootNode(); element = element.parentElement || (root && root.host) || null; if (element && element.messageProtocol && element.messageProtocol.scene) { return element.messageProtocol.scene; } } return 'scene'; } async function callMethod(contextEl, uuid, name, args) { if (!uuid || typeof Editor === 'undefined') return; const protocols = []; const primary = getMessageProtocolScene(contextEl); if (primary) protocols.push(primary); if (protocols.indexOf('scene') < 0) protocols.push('scene'); let lastErr; for (let i = 0; i < protocols.length; i++) { try { await Editor.Message.request(protocols[i], 'execute-component-method', { uuid, name, args: args || [], }); return; } catch (e) { lastErr = e; } } console.warn('[game-controller-inspector]', name, lastErr); } async function findGameControllerUuid(nu) { if (!nu) return null; try { const node = await Editor.Message.request('scene', 'query-node', nu); for (const c of node?.__comps__ || []) { if (c.type === 'GameController' || c.type === '8940aPSKJhGKKIBE/qKnFm7') { return c.value.uuid.value; } } } catch (e) { console.warn('[game-controller-inspector] query-node failed', e); } return null; } async function callGame(contextEl, dump, method, args) { const gc = await findGameControllerUuid(nodeUuid(dump)); if (!gc) { console.warn('[game-controller-inspector] 请先点预览 ▶,等关卡加载后再调试'); return; } await callMethod(contextEl, gc, method, args); } function parseStep(raw) { const n = parseInt(String(raw || '1'), 10); return Number.isNaN(n) || n === 0 ? 1 : n; } let lastDebugAt = 0; function guardDebug(fn) { return () => { const now = Date.now(); if (now - lastDebugAt < 350) return; lastDebugAt = now; fn(); }; } module.exports = Editor.Panel.define({ template: `
`, style: ` .gc-footer { margin-top: 6px; } .gc-footer .hint, .gc-footer .sep { opacity: 0.8; font-size: 11px; margin: 6px 0; display: block; } .gc-footer .row { display: flex; gap: 4px; margin-bottom: 6px; } .gc-footer .lbl { font-size: 11px; align-self: center; min-width: 28px; } .gc-footer .step { flex: 1; } .gc-footer ui-button { flex: 1; } .gc-footer .level-nav { margin-bottom: 4px; } .gc-footer .btn-switch { width: 100%; margin-bottom: 4px; } `, $: { hint: '.hint', step: '.step', btnSwitch: '.btn-switch', btnPrev: '.btn-prev', btnNext: '.btn-next', fwd: '.fwd', back: '.back', jump: '.jump', rotL: '.rot-l', rotR: '.rot-r', info: '.info', end: '.end', veh: '.veh', reset: '.reset', }, ready() { const ctx = () => this.$this || this.$.btnSwitch; const step = () => parseStep(this.$.step.value); this.$.btnPrev.addEventListener('confirm', guardDebug(() => void callGame(ctx(), this.dump, 'prevLevel', []))); this.$.btnNext.addEventListener('confirm', guardDebug(() => void callGame(ctx(), this.dump, 'nextLevel', []))); this.$.btnSwitch.addEventListener('confirm', () => { void callMethod(ctx(), compUuid(this.dump), 'switchLevelFromBootstrap', []); }); this.$.fwd.addEventListener('confirm', guardDebug(() => void callGame(ctx(), this.dump, 'debugMove', [step()]))); this.$.back.addEventListener('confirm', guardDebug(() => void callGame(ctx(), this.dump, 'debugMove', [-step()]))); this.$.jump.addEventListener('confirm', guardDebug(() => void callGame(ctx(), this.dump, 'debugJump', []))); this.$.rotL.addEventListener('confirm', guardDebug(() => void callGame(ctx(), this.dump, 'debugRotateLeft', [1]))); this.$.rotR.addEventListener('confirm', guardDebug(() => void callGame(ctx(), this.dump, 'debugRotateRight', [1]))); this.$.info.addEventListener('confirm', guardDebug(() => void callGame(ctx(), this.dump, 'debugPlayerInfo', []))); this.$.end.addEventListener('confirm', guardDebug(() => void callGame(ctx(), this.dump, 'debugInputEnd', []))); this.$.veh.addEventListener('confirm', guardDebug(() => void callGame(ctx(), this.dump, 'debugVehicleMove', [1]))); this.$.reset.addEventListener('confirm', guardDebug(() => void callGame(ctx(), this.dump, 'debugResetLevel', []))); }, update(dump) { if (dump) this.dump = dump; }, });