Greetings, fellow developers! I am working on a game where you hold a flashlight with a spotlight using the new future lighting. I’m using a viewmodel to hold the flashlight and not a tool. The spotlight and flashlight look really nice, but when I move the camera around, the flashlight looks stuck on the camera. So, I want to make some sort of sway so the flashlight doesn’t look stuck on the camera. However, I don’t really know how to make sway. I think it has something to do with calculating the magnitude and lookVecter, and changing the CFrame of the viewmodel.
Here is the script for the viewmodel:
local player = game:GetService("Players").LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local camera = workspace.Camera
local runService = game:GetService("RunService")
local viewModel = game:GetService("ReplicatedStorage"):WaitForChild("ViewModel"):Clone()
viewModel.Parent = camera
runService.RenderStepped:Connect(function()
if character:FindFirstChild("Humanoid").Health == 0 then
if camera:FindFirstChild("ViewModel") ~= nil then
camera.ViewModel:Destroy()
end
end
if camera:FindFirstChild("ViewModel") ~= nil then
camera.ViewModel:SetPrimaryPartCFrame(camera.CFrame * CFrame.new(0.25,-1.5,-1) * CFrame.Angles(0.05,0,0))
end
end)
So, I feel like I’m getting closer, but I don’t know how to fix this error.
Players.MrFinkyDoodles.PlayerGui.LocalScript:24: attempt to call a nil value
Here is my script:
local runService = game:GetService("RunService")
local replicatedStorage = game:GetService("ReplicatedStorage")
local userInputService = game:GetService("UserInputService")
local modules = replicatedStorage:WaitForChild("Modules")
local SpringModule = require(modules:FindFirstChild("SpringModule"))
local player = game:GetService("Players").LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local camera = workspace.Camera
local viewModel = game:GetService("ReplicatedStorage"):WaitForChild("ViewModel"):Clone()
viewModel.Parent = camera
runService.RenderStepped:Connect(function()
if character:FindFirstChild("Humanoid").Health == 0 then
if camera:FindFirstChild("ViewModel") ~= nil then
camera.ViewModel:Destroy()
end
end
if camera:FindFirstChild("ViewModel") ~= nil then
camera.ViewModel:SetPrimaryPartCFrame(camera.CFrame * CFrame.new(0.25,-1.5,-1) * CFrame.Angles(0.05,0,0))
local mouseDelta = userInputService:GetMouseDelta()
SpringModule:shove(Vector3.new(-mouseDelta.X / 500,mouseDelta.Y / 200,0)) --line with error
local updatedSpring = SpringModule:update(dt)
viewModel:FindFirstChild("HumanoidRootPart").CFrame *= CFrame.new(updatedSpring.X,updatedSpring.Y,0)
end
end)
attempt to perform arithmetic (mul) on nil and number
This error was in the springModule:
-- Constants
local ITERATIONS = 8
-- Module
local SPRING = {}
-- Functions
function SPRING.new(self, mass, force, damping, speed)
local spring = {
Target = Vector3.new();
Position = Vector3.new();
Velocity = Vector3.new();
Mass = mass or 5;
Force = force or 50;
Damping = damping or 4;
Speed = speed or 4;
}
function spring.getstats(self)
return self.Mass, self.Force, self.Damping, self.Speed
end
function spring.changestats(self, mass, force, damping, speed)
self.Mass = mass or self.Mass
self.Force = force or self.Force
self.Damping = damping or self.Damping
self.Speed = speed or self.Speed
end
function spring.shove(self, force)
local x, y, z = force.X, force.Y, force.Z
if x ~= x or x == math.huge or x == -math.huge then
x = 0
end
if y ~= y or y == math.huge or y == -math.huge then
y = 0
end
if z ~= z or z == math.huge or z == -math.huge then
z = 0
end
self.Velocity = self.Velocity + Vector3.new(x, y, z)
end
function spring.update(self, dt)
local scaledDeltaTime = dt * self.Speed / ITERATIONS -- line with error
for i = 1, ITERATIONS do
local iterationForce= self.Target - self.Position
local acceleration = (iterationForce * self.Force) / self.Mass
acceleration = acceleration - self.Velocity * self.Damping
self.Velocity = self.Velocity + acceleration * scaledDeltaTime
self.Position = self.Position + self.Velocity * scaledDeltaTime
end
return self.Position
end
return spring
end
-- Return
return SPRING
I think that’s because you attempted to update the spring by “dt” which you haven’t defined. “dt” stands for deltatime and can be defined inside the brackets of the renderstepped function:
runService.RenderStepped:Connect(function(dt)
Try that and see if it works, if not, send me a model file or place file and I’ll debug it myself.
local player = game:GetService("Players").LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local camera = workspace.Camera
local runService = game:GetService("RunService")
local viewModel = game:GetService("ReplicatedStorage"):WaitForChild("ViewModel"):Clone()
viewModel.Parent = camera
local swayEffect=.7
local swayCFrame=CFrame.new()
local lastCamCFrame=CFrame.new()
runService.RenderStepped:Connect(function()
if character:FindFirstChild("Humanoid").Health == 0 then
if camera:FindFirstChild("ViewModel") ~= nil then
camera.ViewModel:Destroy()
end
end
if camera:FindFirstChild("ViewModel") ~= nil then
local rotation=camera.CFrame:ToObjectSpace(lastCamCFrame)
local X,Y,Z=rotation:ToOrientation()
swayCFrame=swayCFrame:Lerp(CFrame.Angles(math.sin(X)*swayEffect,math.sin(Y)*swayEffect,0),.1)
lastCamCFrame=camera.CFrame
camera.ViewModel:SetPrimaryPartCFrame(camera.CFrame *swayCFrame*CFrame.new(0.25,-1.5,-1))
end
end)