From 9cb5e1abffad27f000ca189a1d3a6c9953515b8d Mon Sep 17 00:00:00 2001 From: gahusb Date: Mon, 15 Jun 2026 08:05:22 +0900 Subject: [PATCH] =?UTF-8?q?feat(lobby):=20=EB=A1=9C=EB=B9=84=20=EC=B9=B4?= =?UTF-8?q?=EB=A9=94=EB=9D=BC=EB=A5=BC=20=ED=94=8C=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=96=B4=20=EC=B6=94=EC=A2=85(follow)=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=E2=80=94=20=EC=A0=84=ED=88=AC=EB=A7=B5=EC=9D=80=20=EA=B3=A0?= =?UTF-8?q?=EC=A0=95=20=EC=9C=A0=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 로비 루트에서 script.MapCamera 제거(고정 framing 억제 해제) + LobbyMobility가 진입 시 ConfineCameraArea=false·ScreenOffset(0.5,0.5)·Zoom 90으로 플레이어 추종 카메라 설정. MSW 카메라는 기본 follow이고 ConfineCameraArea=true가 그걸 억제하므로 false가 핵심. 검증: 로비 우측 이동 시 플레이어 중앙 유지+배경 스크롤, 런 시작→map01 Confine=true 고정, 복귀→follow 복원(누설 없음). Co-Authored-By: Claude Opus 4.8 (1M context) --- RootDesk/MyDesk/LobbyMobility.codeblock | 2 +- map/lobby.map | 6 +----- tools/map/gen-lobby-map.mjs | 13 ++++++------- tools/player/gen-lobby-npc.mjs | 11 +++++++++++ 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/RootDesk/MyDesk/LobbyMobility.codeblock b/RootDesk/MyDesk/LobbyMobility.codeblock index a1396bb..20eb88d 100644 --- a/RootDesk/MyDesk/LobbyMobility.codeblock +++ b/RootDesk/MyDesk/LobbyMobility.codeblock @@ -47,7 +47,7 @@ "Name": null }, "Arguments": [], - "Code": "self.Tries = 0\nlocal eventId = 0\nlocal function apply()\n\tself.Tries = self.Tries + 1\n\tlocal lp = _UserService.LocalPlayer\n\tif lp ~= nil and lp.PlayerControllerComponent ~= nil then\n\t\tlocal pc = lp.PlayerControllerComponent\n\t\tpc.Enable = true\n\t\tpc.FixedLookAt = 0\n\t\tlocal rb = lp.RigidbodyComponent\n\t\tif rb ~= nil then rb.WalkAcceleration = 0.7 end\n\t\tlocal mv = lp.MovementComponent\n\t\tif mv ~= nil then\n\t\t\tmv.InputSpeed = 1.4\n\t\t\tmv.JumpForce = 1.23\n\t\tend\n\t\t_TimerService:ClearTimer(eventId)\n\telseif self.Tries > 50 then\n\t\t_TimerService:ClearTimer(eventId)\n\tend\nend\neventId = _TimerService:SetTimerRepeat(apply, 0.1)", + "Code": "self.Tries = 0\nlocal eventId = 0\nlocal function apply()\n\tself.Tries = self.Tries + 1\n\tlocal lp = _UserService.LocalPlayer\n\tif lp ~= nil and lp.PlayerControllerComponent ~= nil then\n\t\tlocal pc = lp.PlayerControllerComponent\n\t\tpc.Enable = true\n\t\tpc.FixedLookAt = 0\n\t\tlocal rb = lp.RigidbodyComponent\n\t\tif rb ~= nil then rb.WalkAcceleration = 0.7 end\n\t\tlocal mv = lp.MovementComponent\n\t\tif mv ~= nil then\n\t\t\tmv.InputSpeed = 1.4\n\t\t\tmv.JumpForce = 1.23\n\t\tend\n\t\tlocal cam = lp.CameraComponent\n\t\tif cam == nil then cam = _CameraService:GetCurrentCameraComponent() end\n\t\tif cam ~= nil then\n\t\t\tcam.ZoomRatio = 90\n\t\t\tcam.ConfineCameraArea = false\n\t\t\tcam.ScreenOffset = Vector2(0.5, 0.5)\n\t\t\tcam.CameraOffset = Vector2(0, 0)\n\t\tend\n\t\t_TimerService:ClearTimer(eventId)\n\telseif self.Tries > 50 then\n\t\t_TimerService:ClearTimer(eventId)\n\tend\nend\neventId = _TimerService:SetTimerRepeat(apply, 0.1)", "Scope": 2, "ExecSpace": 6, "Attributes": [], diff --git a/map/lobby.map b/map/lobby.map index 7cd8c7b..9637fb4 100644 --- a/map/lobby.map +++ b/map/lobby.map @@ -16,7 +16,7 @@ { "id": "000dbba0-0000-4000-8000-0000000dbba0", "path": "/maps/lobby", - "componentNames": "MOD.Core.MapComponent,MOD.Core.FootholdComponent,script.MapCamera,script.LobbyMobility", + "componentNames": "MOD.Core.MapComponent,MOD.Core.FootholdComponent,script.LobbyMobility", "jsonString": { "name": "lobby", "path": "/maps/lobby", @@ -1104,10 +1104,6 @@ }, "Enable": true }, - { - "@type": "script.MapCamera", - "Enable": true - }, { "@type": "script.LobbyMobility", "Enable": true diff --git a/tools/map/gen-lobby-map.mjs b/tools/map/gen-lobby-map.mjs index f949865..1a7793c 100644 --- a/tools/map/gen-lobby-map.mjs +++ b/tools/map/gen-lobby-map.mjs @@ -97,15 +97,14 @@ for (const e of ents) { const root = ents.find((e) => e.path === '/maps/lobby'); if (!root) throw new Error('[gen-lobby-map] 맵 루트 없음'); -// 로비엔 PlayerLock 제거(이동 허용) + LobbyMobility 추가(이동·공격 해제). MapCamera는 유지. -root.jsonString['@components'] = root.jsonString['@components'].filter( - (c) => !['script.PlayerLock', 'script.LobbyMobility'].includes(c['@type']), -); +// 로비엔 PlayerLock 제거(이동 허용) + MapCamera 제거(고정 framing 대신 follow) + LobbyMobility 추가. +// LobbyMobility가 이동 해제 + 플레이어 추종 카메라를 함께 설정 — MapCamera와 공존하면 +// ConfineCameraArea true/false가 경쟁하므로 MapCamera를 빼야 한다. +const ROOT_STRIP = ['script.PlayerLock', 'script.MapCamera', 'script.LobbyMobility']; +root.jsonString['@components'] = root.jsonString['@components'].filter((c) => !ROOT_STRIP.includes(c['@type'])); root.jsonString['@components'].push({ '@type': 'script.LobbyMobility', Enable: true }); { - const names = (root.componentNames || '') - .split(',') - .filter((s) => s && !['script.PlayerLock', 'script.LobbyMobility'].includes(s)); + const names = (root.componentNames || '').split(',').filter((s) => s && !ROOT_STRIP.includes(s)); names.push('script.LobbyMobility'); root.componentNames = names.join(','); } diff --git a/tools/player/gen-lobby-npc.mjs b/tools/player/gen-lobby-npc.mjs index d968c21..50a20c8 100644 --- a/tools/player/gen-lobby-npc.mjs +++ b/tools/player/gen-lobby-npc.mjs @@ -12,6 +12,9 @@ const WALK_ACCEL = 0.7; const WALK_SPEED = 1.4; const JUMP_FORCE = 1.23; const PROX = 1.2; // 근접 임계(맵 NPC 간격 2.5와 분리) +// 로비 카메라는 전투맵의 고정 framing(ConfineCameraArea=true)과 달리 플레이어를 추종(follow). +// MSW 카메라는 기본이 follow이고 ConfineCameraArea=true가 그걸 억제하므로, false로 풀고 ScreenOffset을 중앙에 둔다. +const LOBBY_ZOOM = 90; // 전투맵과 동일 줌(전환 시 위화감 최소). 플레이테스트로 조정 가능. function prop(Type, Name, DefaultValue = 'nil') { return { Type, DefaultValue, SyncDirection: 0, Attributes: [], Name }; @@ -91,6 +94,14 @@ local function apply() mv.InputSpeed = ${WALK_SPEED} mv.JumpForce = ${JUMP_FORCE} end + local cam = lp.CameraComponent + if cam == nil then cam = _CameraService:GetCurrentCameraComponent() end + if cam ~= nil then + cam.ZoomRatio = ${LOBBY_ZOOM} + cam.ConfineCameraArea = false + cam.ScreenOffset = Vector2(0.5, 0.5) + cam.CameraOffset = Vector2(0, 0) + end _TimerService:ClearTimer(eventId) elseif self.Tries > 50 then _TimerService:ClearTimer(eventId)