feat(lobby): 로비 카메라를 플레이어 추종(follow)으로 — 전투맵은 고정 유지
로비 루트에서 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) <noreply@anthropic.com>
This commit is contained in:
@@ -47,7 +47,7 @@
|
|||||||
"Name": null
|
"Name": null
|
||||||
},
|
},
|
||||||
"Arguments": [],
|
"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,
|
"Scope": 2,
|
||||||
"ExecSpace": 6,
|
"ExecSpace": 6,
|
||||||
"Attributes": [],
|
"Attributes": [],
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
{
|
{
|
||||||
"id": "000dbba0-0000-4000-8000-0000000dbba0",
|
"id": "000dbba0-0000-4000-8000-0000000dbba0",
|
||||||
"path": "/maps/lobby",
|
"path": "/maps/lobby",
|
||||||
"componentNames": "MOD.Core.MapComponent,MOD.Core.FootholdComponent,script.MapCamera,script.LobbyMobility",
|
"componentNames": "MOD.Core.MapComponent,MOD.Core.FootholdComponent,script.LobbyMobility",
|
||||||
"jsonString": {
|
"jsonString": {
|
||||||
"name": "lobby",
|
"name": "lobby",
|
||||||
"path": "/maps/lobby",
|
"path": "/maps/lobby",
|
||||||
@@ -1104,10 +1104,6 @@
|
|||||||
},
|
},
|
||||||
"Enable": true
|
"Enable": true
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"@type": "script.MapCamera",
|
|
||||||
"Enable": true
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"@type": "script.LobbyMobility",
|
"@type": "script.LobbyMobility",
|
||||||
"Enable": true
|
"Enable": true
|
||||||
|
|||||||
@@ -97,15 +97,14 @@ for (const e of ents) {
|
|||||||
|
|
||||||
const root = ents.find((e) => e.path === '/maps/lobby');
|
const root = ents.find((e) => e.path === '/maps/lobby');
|
||||||
if (!root) throw new Error('[gen-lobby-map] 맵 루트 없음');
|
if (!root) throw new Error('[gen-lobby-map] 맵 루트 없음');
|
||||||
// 로비엔 PlayerLock 제거(이동 허용) + LobbyMobility 추가(이동·공격 해제). MapCamera는 유지.
|
// 로비엔 PlayerLock 제거(이동 허용) + MapCamera 제거(고정 framing 대신 follow) + LobbyMobility 추가.
|
||||||
root.jsonString['@components'] = root.jsonString['@components'].filter(
|
// LobbyMobility가 이동 해제 + 플레이어 추종 카메라를 함께 설정 — MapCamera와 공존하면
|
||||||
(c) => !['script.PlayerLock', 'script.LobbyMobility'].includes(c['@type']),
|
// 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 });
|
root.jsonString['@components'].push({ '@type': 'script.LobbyMobility', Enable: true });
|
||||||
{
|
{
|
||||||
const names = (root.componentNames || '')
|
const names = (root.componentNames || '').split(',').filter((s) => s && !ROOT_STRIP.includes(s));
|
||||||
.split(',')
|
|
||||||
.filter((s) => s && !['script.PlayerLock', 'script.LobbyMobility'].includes(s));
|
|
||||||
names.push('script.LobbyMobility');
|
names.push('script.LobbyMobility');
|
||||||
root.componentNames = names.join(',');
|
root.componentNames = names.join(',');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ const WALK_ACCEL = 0.7;
|
|||||||
const WALK_SPEED = 1.4;
|
const WALK_SPEED = 1.4;
|
||||||
const JUMP_FORCE = 1.23;
|
const JUMP_FORCE = 1.23;
|
||||||
const PROX = 1.2; // 근접 임계(맵 NPC 간격 2.5와 분리)
|
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') {
|
function prop(Type, Name, DefaultValue = 'nil') {
|
||||||
return { Type, DefaultValue, SyncDirection: 0, Attributes: [], Name };
|
return { Type, DefaultValue, SyncDirection: 0, Attributes: [], Name };
|
||||||
@@ -91,6 +94,14 @@ local function apply()
|
|||||||
mv.InputSpeed = ${WALK_SPEED}
|
mv.InputSpeed = ${WALK_SPEED}
|
||||||
mv.JumpForce = ${JUMP_FORCE}
|
mv.JumpForce = ${JUMP_FORCE}
|
||||||
end
|
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)
|
_TimerService:ClearTimer(eventId)
|
||||||
elseif self.Tries > 50 then
|
elseif self.Tries > 50 then
|
||||||
_TimerService:ClearTimer(eventId)
|
_TimerService:ClearTimer(eventId)
|
||||||
|
|||||||
Reference in New Issue
Block a user