如何在Roblox中实现不影响角色移动的后视相机功能?
解决Roblox中Outlast风格后视时角色移动方向问题
问题描述
想要实现类似《Outlast》的玩家后视机制:按下Q键切换至后视视角时,角色仍沿身体朝向移动,而非相机当前朝向(如按住W+Q时,角色向前移动同时看向后方)。目前已实现Q键切换相机至后方,但此时角色无法移动,松开Q键后会瞬移到相机朝向对应的移动位置。
问题根源
当相机设为Enum.CameraType.Scriptable后,Roblox默认移动输入逻辑会失效,重新启用相机时还会累积输入导致瞬移。且默认移动以相机朝向为基准,要实现身体朝向移动,需要手动接管WASD输入,以角色根部件朝向为参考计算移动方向。
修改方案
1. 添加状态变量
在变量定义区新增跟踪后视状态和移动输入的变量:
local isLookingBehind = false -- 标记是否处于后视模式 local moveInput = Vector2.new(0, 0) -- 存储WASD的输入状态
2. 监听WASD输入
添加输入监听捕获WASD的按下与释放,实时更新moveInput:
-- 监听WASD按下 UserInputService.InputBegan:Connect(function(input, gameProcessed) if gameProcessed then return end if input.KeyCode == Enum.KeyCode.W then moveInput = moveInput + Vector2.new(0, 1) elseif input.KeyCode == Enum.KeyCode.S then moveInput = moveInput + Vector2.new(0, -1) elseif input.KeyCode == Enum.KeyCode.A then moveInput = moveInput + Vector2.new(-1, 0) elseif input.KeyCode == Enum.KeyCode.D then moveInput = moveInput + Vector2.new(1, 0) end end) -- 监听WASD释放 UserInputService.InputEnded:Connect(function(input) if input.KeyCode == Enum.KeyCode.W then moveInput = moveInput - Vector2.new(0, 1) elseif input.KeyCode == Enum.KeyCode.S then moveInput = moveInput - Vector2.new(0, -1) elseif input.KeyCode == Enum.KeyCode.A then moveInput = moveInput - Vector2.new(-1, 0) elseif input.KeyCode == Enum.KeyCode.D then moveInput = moveInput - Vector2.new(1, 0) end end)
3. 更新后视与相机重置函数
调整lookBehind和camReset,增加状态标记并修复相机跟随逻辑:
local function lookBehind() isLookingBehind = true workspace.CurrentCamera.CameraType = Enum.CameraType.Scriptable end local function camReset() isLookingBehind = false workspace.CurrentCamera.CameraType = Enum.CameraType.Custom workspace.CurrentCamera.CameraSubject = humanoid humanoid:Move(Vector3.new(0,0,0)) -- 清空累积的移动指令,避免瞬移 end
4. 在Heartbeat中处理移动与相机更新
在RunService.Heartbeat回调中添加后视模式的专属逻辑,处理相机跟随和角色移动:
RunService.Heartbeat:Connect(function(deltaTime) -- 新增:后视模式下的相机跟随与移动处理 if isLookingBehind then -- 实时更新相机位置,保持在角色后方 local cameraOffset = CFrame.new(0, 0.5, 0) * CFrame.Angles(0, math.pi, 0) workspace.CurrentCamera.CFrame = root.CFrame * cameraOffset -- 基于角色朝向计算移动方向 if moveInput.Magnitude > 0 then moveInput = moveInput.Unit -- 标准化输入向量 -- 获取角色的前向和右向(忽略Y轴,避免上下移动) local forward = root.CFrame.LookVector * Vector3.new(1, 0, 1) local right = root.CFrame.RightVector * Vector3.new(1, 0, 1) -- 计算最终移动方向 local moveDir = (forward * moveInput.Y) + (right * moveInput.X) humanoid:Move(moveDir.Unit, false) -- false表示忽略相机朝向 else humanoid:Move(Vector3.new(0,0,0)) end end -- 原有的Bob、耐力系统逻辑保持不变 local isMoving = humanoid.MoveDirection.Magnitude > 0 if isMoving and isSprinting==false and isCrouching==false then bobTime = bobTime + (deltaTime * ybobSpeedW) local ybobOffset = math.sin(bobTime)*ybobAmplitudeW humanoid.CameraOffset = Vector3.new(0,ybobOffset,0) elseif isMoving and isSprinting==true and isCrouching==false then bobTime = bobTime + (deltaTime * ybobSpeedS) local ybobOffset = math.sin(bobTime)*ybobAmplitudeS humanoid.CameraOffset = Vector3.new(0,ybobOffset,0) else bobTime=0 if humanoid.CameraOffset.Y >-.5 then humanoid.CameraOffset = Vector3.new(0,0,0) end end if isSprinting==true and stamina > 0 then test.Color = Color3.new(0,1,0) sprint() stamina = math.max(0, stamina - (drainRate*deltaTime)) if stamina <=0 then isSprinting=false walk() test.Color = Color3.new(1,0,0) return end else if (os.clock() - lastStopTime) >= regenDelay then if stamina < maxStamina then stamina = math.min(maxStamina, stamina + (regenRate * deltaTime)) end end end updateStaminaUI() end)
5. 调整原有输入监听
将Q键的输入处理合并到原有逻辑中,确保状态正确切换:
UserInputService.InputBegan:Connect(function(input, gameProcessed) if gameProcessed then return end if input.KeyCode == Enum.KeyCode.LeftShift and stamina > 0 then isSprinting=true elseif input.KeyCode == Enum.KeyCode.LeftControl then crouch() elseif input.KeyCode == Enum.KeyCode.Q then lookBehind() end end) UserInputService.InputEnded:Connect(function(input) if input.KeyCode == Enum.KeyCode.LeftShift then lastStopTime = os.clock() walk() isSprinting=false test.Color = Color3.new(1,0,0) elseif input.KeyCode == Enum.KeyCode.LeftControl then humanoid.BodyHeightScale.Value = 1 walk() uncrouch() elseif input.KeyCode == Enum.KeyCode.Q then camReset() end end)
修改后效果
按下Q进入后视模式时,WASD会以角色当前身体朝向为基准移动(W=角色前方,S=角色后方),相机保持在角色后方实时跟随;松开Q后恢复正常相机控制,不会出现瞬移问题。
内容的提问来源于stack exchange,提问作者mar sky
相关产品推荐
相关产品推荐

