Hi, like the title says, I want to restrict the player’s camera movement.
Let me explain: I have a script that moves the camera using WASD. It works perfectly, however, I want to restrict it so it can only go 75 studs to the left and right, 150 studs forward, and 10 studs backwards.
Here is my script:
local limits = {
Forward = 150,
Left = 75,
Right = 75,
Back = 10
}
local RunS = game:GetService("RunService")
local TagS = game:GetService("CollectionService")
local InputS = game:GetService("UserInputService")
local camera = game.Workspace.CurrentCamera
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local originalPos = camera.CFrame
local screen = Instance.new("ScreenGui", player.PlayerGui)
local CAMERA_MOVE_SPEED_MAX = 30
local CAMERA_MOVE_FORCE = 150
local cameraVelocity = Vector3.zero
function getCameraMoveDirInput(): Vector3
local dir = Vector3.zero
if InputS:IsKeyDown(Enum.KeyCode.D) then dir += Vector3.xAxis end
if InputS:IsKeyDown(Enum.KeyCode.A) then dir -= Vector3.xAxis end
if InputS:IsKeyDown(Enum.KeyCode.S) then dir += Vector3.zAxis end
if InputS:IsKeyDown(Enum.KeyCode.W) then dir -= Vector3.zAxis end
if dir ~= Vector3.zero then
dir = dir.Unit
end
return dir
end
function clampV3Magnitude(v: Vector3, min: number, max:number): Vector3
return v.Unit * math.clamp(v.Magnitude, min, max)
end
function updateCameraMovement(dt)
local accelDir = getCameraMoveDirInput()
if accelDir ~= Vector3.zero then
cameraVelocity += CAMERA_MOVE_FORCE * accelDir * dt
cameraVelocity = clampV3Magnitude(cameraVelocity, 0, CAMERA_MOVE_SPEED_MAX)
else
cameraVelocity *= math.clamp(1 - (15 * dt), 0, 1)
end
camera.CFrame += cameraVelocity * dt
end
function updateCamera(dt)
updateCameraMovement(dt)
end
camera.CameraType = Enum.CameraType.Scriptable
camera:GetPropertyChangedSignal("CameraType"):Connect(function()
camera.CameraType = Enum.CameraType.Scriptable
end)
RunS.RenderStepped:Connect(updateCamera)
To restrict the camera’s movement within the specified limits, you should use a clamping function to constrain the camera’s position based on the limits before applying the movement.
function clampPosition(pos, originalPos, limits)
local x = math.clamp(pos.X, originalPos.X - limits.Left, originalPos.X + limits.Right)
local y = pos.Y – assuming you don’t want to clamp Y movement
local z = math.clamp(pos.Z, originalPos.Z - limits.Back, originalPos.Z + limits.Forward)
return Vector3.new(x, y, z)
end
function updateCameraMovement(dt)
local accelDir = getCameraMoveDirInput()
local limits = {
Forward = 150,
Left = 75,
Right = 75,
Back = 10
}
local RunS = game:GetService("RunService")
local TagS = game:GetService("CollectionService")
local InputS = game:GetService("UserInputService")
local camera = game.Workspace.CurrentCamera
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local originalPos = camera.CFrame
local screen = Instance.new("ScreenGui", player.PlayerGui)
local CAMERA_MOVE_SPEED_MAX = 30
local CAMERA_MOVE_FORCE = 150
local cameraVelocity = Vector3.zero
function getCameraMoveDirInput(): Vector3
local dir = Vector3.zero
if InputS:IsKeyDown(Enum.KeyCode.D) then dir += Vector3.xAxis end
if InputS:IsKeyDown(Enum.KeyCode.A) then dir -= Vector3.xAxis end
if InputS:IsKeyDown(Enum.KeyCode.S) then dir += Vector3.zAxis end
if InputS:IsKeyDown(Enum.KeyCode.W) then dir -= Vector3.zAxis end
if dir ~= Vector3.zero then
dir = dir.Unit
end
return dir
end
function clampV3Magnitude(v: Vector3, min: number, max:number): Vector3
return v.Unit * math.clamp(v.Magnitude, min, max)
end
function clampPosition(pos, originalPos, limits)
local x = math.clamp(pos.X, originalPos.X - limits.Left, originalPos.X + limits.Right)
local y = pos.Y -- assuming you don't want to clamp Y movement
local z = math.clamp(pos.Z, originalPos.Z - limits.Back, originalPos.Z + limits.Forward)
return Vector3.new(x, y, z)
end
function updateCameraMovement(dt)
local accelDir = getCameraMoveDirInput()
if accelDir ~= Vector3.zero then
cameraVelocity += CAMERA_MOVE_FORCE * accelDir * dt
cameraVelocity = clampV3Magnitude(cameraVelocity, 0, CAMERA_MOVE_SPEED_MAX)
else
cameraVelocity *= math.clamp(1 - (15 * dt), 0, 1)
end
local newPosition = camera.CFrame.Position + cameraVelocity * dt
newPosition = clampPosition(newPosition, originalPos.Position, limits)
camera.CFrame = CFrame.new(newPosition) * CFrame.Angles(camera.CFrame:ToOrientation())
end
function updateCamera(dt)
updateCameraMovement(dt)
end
camera.CameraType = Enum.CameraType.Scriptable
camera:GetPropertyChangedSignal("CameraType"):Connect(function()
camera.CameraType = Enum.CameraType.Scriptable
end)
RunS.RenderStepped:Connect(updateCamera)