fix(player): клик по 3D-табличкам в third-person (свободный курсор)
_handlePlayClick пикал билборд из ЦЕНТРА экрана (w/2,h/2) — верно только при pointer-lock. В third курсор свободен, юзер кликает мышью НЕ в центре → pick промахивался, кнопки табличек не нажимались (Ферма 1981 и др). Фикс: onMouseDown передаёт реальные canvas-координаты клика в _handlePlayClick(clickX,clickY); при locked — центр, иначе — точка клика. Добавлен console.log [billboard] для диагностики попадания. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
fe23d099cd
commit
7b869c83bd
@ -2183,8 +2183,12 @@ export class BabylonScene {
|
||||
const onMouseDown = (e) => {
|
||||
if (this._isPlaying) {
|
||||
// В Play-режиме ЛКМ — клик игрока в forward-направлении.
|
||||
// Pointer Lock — курсор всё равно в центре экрана.
|
||||
if (e.button === 0) this._handlePlayClick();
|
||||
// При pointer-lock курсор в центре; в third (свободный курсор)
|
||||
// передаём реальные координаты клика для pick по табличкам.
|
||||
if (e.button === 0) {
|
||||
const r = canvas.getBoundingClientRect();
|
||||
this._handlePlayClick(e.clientX - r.left, e.clientY - r.top);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Обновляем pointer координаты для raycast и Gizmo
|
||||
@ -2913,7 +2917,7 @@ export class BabylonScene {
|
||||
* - в self-обработчики скриптов (routeEvent с target)
|
||||
* - в глобальные обработчики (game.onClick) с event.target
|
||||
*/
|
||||
_handlePlayClick() {
|
||||
_handlePlayClick(clickX, clickY) {
|
||||
if (!this._isPlaying) return;
|
||||
|
||||
// Мультиплеер-выстрел: если у сцены есть mpSync, шлём 'shoot' серверу.
|
||||
@ -2936,12 +2940,17 @@ export class BabylonScene {
|
||||
if (!this.gameRuntime) return;
|
||||
|
||||
// === Задача 01: клик по КНОПКЕ 3D-таблички (billboard) ===
|
||||
// Пикаем из центра экрана (как _pickFromCenter — в Play обычно
|
||||
// pointer-lock). Если попали в кнопку таблички → fireClick и выходим.
|
||||
// При pointer-lock (first/shift-lock) курсор в центре экрана → пикаем
|
||||
// из центра. В third курсор СВОБОДНЫЙ → пикаем по реальным координатам
|
||||
// клика (clickX/clickY переданы из onMouseDown). Без этого клик по
|
||||
// табличке мышью в third промахивался — кнопки не нажимались.
|
||||
if (this.billboardUiManager && this.primitiveManager) {
|
||||
const locked = (document.pointerLockElement === this.canvas);
|
||||
const w = this.engine?.getRenderWidth?.() || this.canvas.width;
|
||||
const h = this.engine?.getRenderHeight?.() || this.canvas.height;
|
||||
const bpick = this.scene.pick(w / 2, h / 2, (m) =>
|
||||
const px = locked ? w / 2 : (Number.isFinite(clickX) ? clickX : w / 2);
|
||||
const py = locked ? h / 2 : (Number.isFinite(clickY) ? clickY : h / 2);
|
||||
const bpick = this.scene.pick(px, py, (m) =>
|
||||
m && m.metadata && m.metadata.primitiveId != null
|
||||
&& this.primitiveManager.instances.get(m.metadata.primitiveId)?.type === 'billboard');
|
||||
if (bpick && bpick.hit && bpick.pickedMesh) {
|
||||
@ -2949,10 +2958,16 @@ export class BabylonScene {
|
||||
const uv = bpick.getTextureCoordinates ? bpick.getTextureCoordinates() : null;
|
||||
if (bdata && uv) {
|
||||
const buttonId = this.billboardUiManager.pickButtonAt(bdata, uv.x, uv.y);
|
||||
console.log('[billboard] клик id=' + bpick.pickedMesh.metadata.primitiveId
|
||||
+ ' uv=(' + uv.x.toFixed(2) + ',' + uv.y.toFixed(2) + ') buttonId=' + buttonId
|
||||
+ ' locked=' + locked);
|
||||
if (buttonId) {
|
||||
this.billboardUiManager.fireClick(bdata, buttonId);
|
||||
return; // клик по табличке обработан
|
||||
}
|
||||
} else {
|
||||
console.log('[billboard] попал в табличку id='
|
||||
+ bpick.pickedMesh.metadata.primitiveId + ' но нет UV');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user