so i have this local script here. it worked just fine, until a few minutes ago when i opened the place and playtested it. all of a sudden, i’m getting an error, specifically for the blue part, ‘c_calmSeaside’. ‘Players.Ultimax_84.PlayerScripts.zoneHandler:74: attempt to index nil with ‘associatedFOV’’. i am thoroughly puzzled, because this error seems to only be thrown around half the time…
(for display, i made the camera parts visible.)
my setup:
-
there are 2 folders in the workspace: “ambienceFolder” and “cameraParts”.
-
inside of the ambience folder, there are the non-collidable parts that i create zones for.
-
in the camera parts folder, there are small invisible parts that the camera’s base CFrame is set to upon entering the zone. it looks at the HumanoidRootPart of your avatar, and uses CFrame:Lerp() as an alternative to constantly creating and destroying tweens.
-
in the camera parts themselves, there is a NumberValue, called “associatedFOV”. this is the value that the camera’s FOV tweens to, when inside of the zone.
-
inside of SoundService, there is a folder called “ambientSounds”. each of these sounds is playing, but their volume is set to 0. once a player enters a zone, it looks to see if there is a sound that shares a name with a zone. if there is, it tween’s the sound’s volume to 1, and back to 0 once the zone is exited.
-
each zone has a corresponding camera part (in the camera part folder), but has “c_” at the start of the name.
-
there are 4 zones: calmSeaside, consumerism, creepyFog, and sunset.
my script:
-- uses ZonePlus by ForeverHD
local currentCamera = workspace.CurrentCamera
local oldFOV = currentCamera.FieldOfView
local lighting = game:GetService("Lighting")
local defaultLighting = lighting.OutdoorAmbient
local tweenService = game:GetService("TweenService")
local replicatedStorage = game:GetService("ReplicatedStorage")
local zonePlus = require(replicatedStorage:WaitForChild("Zone"))
local ambienceFolder = workspace:FindFirstChild("ambienceFolder")
local localPlayer = game:GetService("Players").LocalPlayer
local cameraPartFolder = workspace:FindFirstChild("cameraParts")
local zoneController = require(replicatedStorage.Zone.ZoneController)
local soundService = game:GetService("SoundService")
local runService = game:GetService("RunService")
local lerpFactor = 0.08
local runServiceConnection
local ambientParts = {
ambienceFolder:WaitForChild("calmSeaside"),
ambienceFolder:WaitForChild("consumerism"),
ambienceFolder:WaitForChild("sunset"),
ambienceFolder:WaitForChild("creepyFog")
}
local cameraTweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out)
local tweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Circular, Enum.EasingDirection.InOut)
local propertyTable = {Volume = 1}
local propertyTable2 = {Volume = 0}
function captureAndResetCFrame(object: BasePart, cachedCFrame: CFrame)
if object and cachedCFrame then
object.CFrame = cachedCFrame
end
end
for _, zonePart in ipairs(ambientParts) do
local ambientZone = zonePlus.new(zonePart)
local audioFile = soundService.ambientSounds:WaitForChild(tostring(zonePart.Name))
local lightingGoal = {OutdoorAmbient = zonePart.Color}
local lightingExit = {OutdoorAmbient = defaultLighting}
ambientZone:bindToGroup("ambientAreas")
local camPart = cameraPartFolder:FindFirstChild("c_" .. tostring(zonePart.Name))
local cachedCFrame -- store the initial cframe
-- player entered and exited
ambientZone.localPlayerEntered:Connect(function()
local tween = tweenService:Create(audioFile, tweenInfo, propertyTable):Play()
local lightingTween = tweenService:Create(lighting, tweenInfo, lightingGoal):Play()
print(camPart)
if camPart then
local fov = tonumber(camPart.associatedFOV.Value)
currentCamera.CameraType = Enum.CameraType.Scriptable
cachedCFrame = camPart.CFrame -- cframe captured
runServiceConnection = runService.RenderStepped:Connect(function()
currentCamera.CFrame = camPart.CFrame
local targetPart = localPlayer.Character.PrimaryPart
local lookAtPosition = targetPart.Position
local currentPosition = camPart.Position
local lookAtCFrame = CFrame.new(currentPosition, lookAtPosition)
camPart.CFrame = camPart.CFrame:Lerp(lookAtCFrame, lerpFactor)
end)
local fovTween = tweenService:Create(currentCamera, cameraTweenInfo, {FieldOfView = fov}):Play()
end
end)
ambientZone.localPlayerExited:Connect(function()
print(camPart)
local lightingTween = tweenService:Create(lighting, tweenInfo, lightingExit):Play()
local fov = tonumber(camPart.associatedFOV.Value)
if runServiceConnection then
runServiceConnection:Disconnect()
-- reset the cframe
captureAndResetCFrame(camPart, cachedCFrame)
end
local fovTween = tweenService:Create(currentCamera, cameraTweenInfo, {FieldOfView = oldFOV}):Play()
currentCamera.CameraType = Enum.CameraType.Custom
local tween = tweenService:Create(audioFile, tweenInfo, propertyTable2):Play()
end)
end
local dictionary = {
onlyEnterOnceExitedAll = true,
}
zoneController.setGroup("ambientAreas", dictionary)