fix(studio): дверь-код подсказка E только при открытой, NPC=R15-скин (анимация рук/ног), торговец видимый
1) Дверь по коду: подсказка «E закрыть» теперь только когда дверь открыта и игрок рядом (через onKey+onTick, без постоянного interact-промпта). 2) NPC-киты используют R15-скин 'skin_roblox-noob' → процедурная анимация бега/покоя с руками и ногами (R15Animator), вместо безжизненного покачивания. 3) Торговец-кит: невидимый триггер (insertGameplayKit теперь уважает prim.visible=false, раньше хардкод visible:true) + NPC-персонаж рядом — синий куб больше не виден. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
9903719f9d
commit
26e6306f6e
@ -800,7 +800,7 @@ const KubikonEditor = () => {
|
||||
x: px + (p.x || 0), y: py + (p.y != null ? p.y : 1), z: pz + (p.z || 0),
|
||||
sx: p.sx, sy: p.sy, sz: p.sz,
|
||||
color: p.color, material: p.material,
|
||||
canCollide: p.canCollide !== false, visible: true, anchored: true,
|
||||
canCollide: p.canCollide !== false, visible: p.visible !== false, anchored: true,
|
||||
name: p.name,
|
||||
});
|
||||
if (newId != null) {
|
||||
|
||||
@ -617,10 +617,15 @@ function place(a){
|
||||
}
|
||||
game.onTick((dt) => {
|
||||
if (cur !== target){ const st=SPEED*dt; cur = Math.abs(target-cur)<=st ? target : cur+Math.sign(target-cur)*st; place(cur); }
|
||||
if (opened) return;
|
||||
// Поле ввода появляется/прячется по дистанции.
|
||||
const pl = game.player.position;
|
||||
const d = Math.sqrt((pl.x-p0.x)**2 + (pl.z-p0.z)**2);
|
||||
if (opened){
|
||||
// Дверь открыта: подсказка «E закрыть» только когда игрок рядом.
|
||||
if (d < RADIUS && !near){ near = true; game.ui.set('codehint','Нажми E чтобы закрыть дверь', {x:50,y:80,anchor:'bottom',color:'#fff',size:16}); }
|
||||
else if (d >= RADIUS && near){ near = false; game.ui.set('codehint','',{}); }
|
||||
return;
|
||||
}
|
||||
// Дверь закрыта: поле ввода кода по дистанции.
|
||||
if (d < RADIUS && !near){ near = true;
|
||||
game.gui.create('textbox', { id:'codein', x:50, y:86, w:24, h:8, anchor:'center', placeholder:'Код...', textSize:20 });
|
||||
game.ui.set('codehint', '🔢 Введи код двери (1234) и нажми Enter', {x:50,y:78,anchor:'bottom',color:'#fff',size:16}); }
|
||||
@ -629,19 +634,21 @@ game.onTick((dt) => {
|
||||
game.gui.onSubmit('codein', (text) => {
|
||||
if (opened) return;
|
||||
if (String(text).trim() === CODE){
|
||||
opened = true; target = Math.PI/2; // плавно распахнуть
|
||||
opened = true; near = false; target = Math.PI/2; // плавно распахнуть
|
||||
game.gui.remove('codein');
|
||||
game.ui.set('codehint','✓ Открыто! Нажми E чтобы закрыть.', {x:50,y:78,anchor:'bottom',color:'#36d57a',size:16});
|
||||
game.after(2.5, () => game.ui.set('codehint','',{}));
|
||||
game.ui.set('codehint','✓ Открыто!', {x:50,y:78,anchor:'bottom',color:'#36d57a',size:18});
|
||||
game.after(2, () => game.ui.set('codehint','',{}));
|
||||
} else game.ui.set('codehint','✗ Неверный код', {x:50,y:78,anchor:'bottom',color:'#ff5555',size:18});
|
||||
});
|
||||
// Закрыть открытую дверь по E → снова можно вводить код.
|
||||
game.self.onInteract(() => {
|
||||
// Закрыть дверь по E (только если открыта и игрок рядом).
|
||||
game.onKey('e', () => {
|
||||
if (!opened) return;
|
||||
opened = false; near = false; target = 0; // плавно закрыть
|
||||
game.ui.set('codehint','🔒 Дверь закрыта.', {x:50,y:78,anchor:'bottom',color:'#fff',size:16});
|
||||
game.after(2, () => game.ui.set('codehint','',{}));
|
||||
}, { text: 'Закрыть дверь', key: 'e', distance: 4 });` }],
|
||||
const pl = game.player.position;
|
||||
if (Math.sqrt((pl.x-p0.x)**2 + (pl.z-p0.z)**2) >= RADIUS) return;
|
||||
opened = false; near = false; target = 0;
|
||||
game.ui.set('codehint','🔒 Дверь закрыта.', {x:50,y:80,anchor:'bottom',color:'#fff',size:16});
|
||||
game.after(1.5, () => game.ui.set('codehint','',{}));
|
||||
});` }],
|
||||
},
|
||||
{
|
||||
id: 'name-label',
|
||||
@ -708,7 +715,7 @@ game.onTick(() => {
|
||||
icon: 'chase', category: 'npc',
|
||||
scripts: [{ attachTo: 'global', code:
|
||||
`// Спавним NPC, который преследует игрока.
|
||||
const enemy = game.scene.spawnNpc('character-a', { x: 8, z: 8, name: 'Охотник', speed: 4 });
|
||||
const enemy = game.scene.spawnNpc('skin_roblox-noob', { x: 8, z: 8, name: 'Охотник', speed: 4 });
|
||||
if (enemy && enemy.follow) enemy.follow('player');` }],
|
||||
},
|
||||
{
|
||||
@ -721,7 +728,7 @@ if (enemy && enemy.follow) enemy.follow('player');` }],
|
||||
scripts: [{ attachTo: 'on-target', code:
|
||||
`// Торговец — настоящий NPC-персонаж. Триггер (этот объект) держит диалог по E.
|
||||
const p = game.self.position;
|
||||
const npc = game.scene.spawnNpc('character-a', { x: p.x, z: p.z, name: 'Торговец Боб' });
|
||||
const npc = game.scene.spawnNpc('skin_roblox-noob', { x: p.x, z: p.z, name: 'Торговец Боб' });
|
||||
game.self.onInteract(() => {
|
||||
game.modal.dialog('Торговец Боб', [
|
||||
'Привет, путник! Заходи за товарами.',
|
||||
@ -777,7 +784,7 @@ game.self.onClick(() => {
|
||||
`// Каждые 5с спавнит 2 врагов из точки портала, они идут к игроку.
|
||||
const p = game.self.position;
|
||||
function wave(){
|
||||
for (let i=0;i<2;i++){ const e = game.scene.spawnNpc('character-a', { x:p.x+(Math.random()-0.5)*2, z:p.z+(Math.random()-0.5)*2, name:'Враг', speed:3 });
|
||||
for (let i=0;i<2;i++){ const e = game.scene.spawnNpc('skin_roblox-noob', { x:p.x+(Math.random()-0.5)*2, z:p.z+(Math.random()-0.5)*2, name:'Враг', speed:3 });
|
||||
if (e && e.follow) e.follow('player'); }
|
||||
}
|
||||
game.after(2, wave); game.every(5, wave);` }],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user