Dynamic Field of View

Hello. I am making a swinging game (like spiderman) and I want to make it so that the faster you go, the FOV gets higher so it feels like you’re going insanely fast. I am not sure how to calculate the speed though and correspond it with a higher FOV. If someone could help me that would be fantastic! :+1:

You’d most likey wanna check out Humanoid.WalkSpeed and Camera.FieldOfView.

Here are some external links to help you out:
https://create.roblox.com/docs/reference/engine/classes/Humanoid
https://create.roblox.com/docs/reference/engine/classes/Camera

In your case, you’d want to increase the field of view based of the speed, so you’d want something like:

local camera = ...
local humanoid = ...
local defaultFOV = 70 -- change this as you please
local defaultWalkSpeed = 16 -- change this as you please 

humanoid:GetPropertyChangedSignal(“WalkSpeed”):Connect(function()
    camera.FieldOfView = defaultFOV * (humanoid.WalkSpeed / defaultWalkSpeed) 
    -- most of this would just be very basic math^
end) 

This is untested but you should get the right idea!

3 Likes

Keeps throwing an error that says Humanoid is not a valid member of Model workspace.MyUser on line 3 and I have no idea why.

local camera = workspace.CurrentCamera.FieldOfView
local char = game.Players.LocalPlayer.Character or game.Players.LocalPlayer.CharacterAdded:Wait()
local humanoid = char.Humanoid
local defaultFOV = 70 -- change this as you please
local defaultWalkSpeed = 16 -- change this as you please

humanoid:GetPropertyChangedSignal("Walkspeed"):Connect(function()
	camera.FieldOfView = defaultFOV * (humanoid.WalkSpeed / defaultWalkSpeed) 
	-- most of this would just be very basic math^
end)

I’d suggest putting that script in StarterCharacterScripts instead of StarterPlayerScripts if that is your case currently.

If you do put it in StarterCharacterScripts I’d suggest modifying it a bit to:

local camera = workspace.CurrentCamera.FieldOfView
local char = script.Parent
local humanoid = char:WaitForChild('Humanoid')
local defaultFOV = 70 -- change this as you please
local defaultWalkSpeed = 16 -- change this as you please

humanoid:GetPropertyChangedSignal("Walkspeed"):Connect(function()
	camera.FieldOfView = defaultFOV * (humanoid.WalkSpeed / defaultWalkSpeed) 
	-- most of this would just be very basic math^
end)
3 Likes

It’s currently in StarterGUI but I will move it and see if this fixes anything. Thanks so much!

Ok, now it says that WalkSpeed is not a valid property name.

ok nevermind lol this is a lot of edits. I fixed it but now it just doesn’t work. No errors in the output.

Yup it’s supposed to be WalkSpeed not Walkspeed. Once again untested code so it’s bound to happen :sweat_smile:

final script, try this:

local camera = workspace.CurrentCamera
local char = script.Parent
local humanoid = char:WaitForChild('Humanoid')
local defaultFOV = 70 -- change this as you please
local defaultWalkSpeed = 16 -- change this as you please

humanoid:GetPropertyChangedSignal("WalkSpeed"):Connect(function()
	camera.FieldOfView = defaultFOV * (humanoid.WalkSpeed / defaultWalkSpeed) 
	-- most of this would just be very basic math^
end)

If you are looking for a much smoother outcome, check out Roblox’s TweenService

2 Likes

Yup, I tried this but it doesn’t work. No errors in the output.

1 Like

Hmm works fine with me, remember this is using WalkSpeed not the characters velocity. Using the characters velocity would still be the same concept.

For me:
image

walk speed is equal to 16:

walk speed is equal to 25:

1 Like

Oh yeah, sorry I didn’t realize that :sweat_smile:. How would I make it so that it’s based off of the velocity?

Well it would most likely use the same math concept just sorta tweaked. You’d most likely want to use AssemblyLinearVelocity.Magnitude in place of WalkSpeed.

1 Like

So like :GetPropertyChangedSignal(“AssemblyLinearVelocity”)???

Also would defaultWalkSpeed be tweaked or remain the same in the formula?

And be sure to get the new Velocity in a while true do loop, or in a function that checks for change in the Velocity.

What do you mean by that?

I’m just confused about how to check the Velocity changing

It’s a Property of a Part.
A value in studs/second.
BasePart.AssemblyLinearVelocity

So in the script you posted:

local humanoid = char:WaitForChild('Humanoid')
local velocity = humanoid.RootPart.Velocity

humanoid:GetPropertyChangedSignal(velocity):Connect(function()
	camera.FieldOfView = defaultFOV * (humanoid.WalkSpeed / defaultWalkSpeed) 
	-- most of this would just be very basic math^**
end)

Not quite… GetPropertyChangedSignal takes a string not a vector3, and the code still changes based on walkspeed so that wouldn’t work either. Something like this should probably do the trick (Reply if there’s a bug I didn’t test it. Code goes in Localscript preferably in startercharacterscripts although startergui works too):

local player = game.Players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()

local camera = workspace.CurrentCamera

local max = 120
local min = 70
local dampen = 10

char.PrimaryPart:GetPropertyChangedSignal("Velocity"):Connect(function()
	camera.FieldOfView = math.clamp(70 + char.PrimaryPart.Velocity.Magnitude/dampen,min,max) -- tweak around with dampen to increase/decrease the linear change in fov
end)

Edit: You can also use tweeting to make it a bit smoother but it is optional.

2 Likes

Hehe, yeah, it’s a string.
Late night and not a whole lot of experience with the finer points of scripting yet.
I often know the procedures of how to make things work, I just don’t have the skills to type out the lines of code properly so lua can understand what I’m trying to do…

If I’m not mistaken I don’t think properties like Velocity, Position, CFrame fire GetPropertyChangedSignal because of how frequently they change.

3 Likes

I’m pretty sure they do, however in the case they don’t the alternative is just to use renderstepped.