How to make a 3rd person vehicle seat camera have limits

I would like to achieve an affect where I cannot allow the player’s camera to go past Y = 0 (Camera cannot go below the vehicle basically) with a damping effect. I’m not sure on how to achieve this effect nor I cannot really showcase what I have in mind because my computer is slow and cannot record smooth gameplay but hopefully my explaination was enough.

1 Like

You can solve this problem as follows:

  1. Press Play and then copy both of these scripts

  1. After that press Stop and paste both scripts into StarterPlayerScripts

  2. Put VehicleCamera module inside PlayerScriptsLoader

  3. Inside VehicleCamera module replace lines 93 and 94 with

local pitchSpringPosNotClamped = pitchSpring.pos + dPitch

local cameraSubject = workspace.CurrentCamera.CameraSubject
local pitchLowerLimitValue = cameraSubject:FindFirstChild("PitchLowerLimit")
if pitchLowerLimitValue and pitchLowerLimitValue:IsA("NumberValue") then
	local pitchLowerLimit = math.rad(pitchLowerLimitValue.Value)
	local pitchLowerLimitStiffness = DEFAULT_PITCH_LOWER_LIMIT_STIFFNESS

	local pitchLowerLimitStiffnessValue = cameraSubject:FindFirstChild("PitchLowerLimitStiffness")
	if pitchLowerLimitStiffnessValue and pitchLowerLimitStiffnessValue:IsA("NumberValue") then
		pitchLowerLimitStiffness = pitchLowerLimitStiffnessValue.Value
	end

	if pitchSpringPosNotClamped > pitchLowerLimit then
		pitchSpringPosNotClamped += (pitchLowerLimit - pitchSpringPosNotClamped) * (1 - math.exp(-dt * pitchLowerLimitStiffness))
	end
end

yawSpring.pos = sanitizeAngle(yawSpring.pos + dYaw)
pitchSpring.pos = sanitizeAngle(math.clamp(pitchSpringPosNotClamped, -PITCH_LIMIT, PITCH_LIMIT))
  1. and after line 8 add this line, this will set the default stiffness for the limit
local DEFAULT_PITCH_LOWER_LIMIT_STIFFNESS = 16
  1. then change PlayerScriptsLoader’s code to
--[[
	PlayerScriptsLoader - This script requires and instantiates the PlayerModule singleton

	2018 PlayerScripts Update - AllYourBlox
--]]

local NewVehicleCamera = script:WaitForChild("VehicleCamera")

local PlayerModule = script.Parent:WaitForChild("PlayerModule")
local CameraModule = PlayerModule:WaitForChild("CameraModule")

CameraModule:WaitForChild("VehicleCamera"):Destroy()

NewVehicleCamera.Parent = CameraModule

require(PlayerModule)

  1. And inside of the VehicleSeats that you want to have the limit, insert a NumberValue and rename it to PitchLowerLimit, then set the value of it to how much do you want the players to be able to rotate the camera down before the limit starts working

  2. optionally you can add another NumberValue inside of it called PitchLowerLimitStiffness,
    then set the value of it to how stiff do you want the limit to be (a bigger value will make the limit less smooth, while a smaller value will make the limit more smooth)

The smooth limit works by checking if a player has rotated the camera downwards more than a certain angle and then it interpolates the camera back to that certain angle which makes it smooth

And the replaced code of PlayerScriptsLoader will replace the Roblox VehicleCamera with the new VehicleCamera that smoothly limits the camera’s vertical rotation

3 Likes

Could you send me a place file? VehicleCamera seems to not be running

2 Likes

Here you go!
I made a VehicleSeat that you can sit on and test
VehicleCameraPitchLowerLimit.rbxl (62.9 KB)

Hey this is excellent however it does not work with my custom camera scripts. It should work all I did was put the number values in the respect Camera Parts but it does not work. Any ideas why?

I thought that you needed help with the Roblox camera.
Sorry but I don’t really want to figure out someone’s custom camera

No no all I do is just the camera subject so it shouldn’t be a problem.

Here you go

Now you can insert the NumberValues into the camera subjects that you want to have the limit and it should work

Make a LocalScript in StarterPlayerScripts and replace it’s code with

local DEFAULT_PITCH_LOWER_LIMIT_STIFFNESS = 16

local RunService = game:GetService("RunService")

local Camera = workspace.CurrentCamera

local WorldDt = 0

RunService.Stepped:Connect(function(_, dt)
	WorldDt = dt
end)

RunService.RenderStepped:Connect(function()
	local dt = WorldDt
	WorldDt = 0
	
	local RotX, RotY, RotZ = Camera.CFrame:ToEulerAnglesYXZ()
	
	local cameraSubject = Camera.CameraSubject
	if cameraSubject then
		local pitchLowerLimitValue = cameraSubject:FindFirstChild("PitchLowerLimit")
		if pitchLowerLimitValue and pitchLowerLimitValue:IsA("NumberValue") then
			local pitchLowerLimit = math.rad(pitchLowerLimitValue.Value)
			local pitchLowerLimitStiffness = DEFAULT_PITCH_LOWER_LIMIT_STIFFNESS

			local pitchLowerLimitStiffnessValue = cameraSubject:FindFirstChild("PitchLowerLimitStiffness")
			if pitchLowerLimitStiffnessValue and pitchLowerLimitStiffnessValue:IsA("NumberValue") then
				pitchLowerLimitStiffness = pitchLowerLimitStiffnessValue.Value
			end

			if RotX > pitchLowerLimit then
				RotX += (pitchLowerLimit - RotX) * (1 - math.exp(-dt * pitchLowerLimitStiffness))
			end
		end
		
		local Focus = Camera.Focus.Position
		local Zoom = (Camera.CFrame.Position - Focus).Magnitude
		
		Camera.CFrame = CFrame.fromEulerAnglesYXZ(RotX, RotY, RotZ) * CFrame.new(0, 0, Zoom) + Focus
	end
end)

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.