I have created this localscript called localgunscript that makes the player aim a tool to wherever the mouse is pointing. It works by setting the c0 of the waist motor6d, and runs every heartbeat. However, as seen in the video, it has a high script performance, ranging from 0.2% to 1.1% How do I optimize the code so it becomes lower? The code is below the video:
local Tool = script.Parent
local Player = game.Players.LocalPlayer
local Mouse = Player:GetMouse()
local origc0 = nil
Tool.Equipped:Connect(function()
if not game.UserInputService.VREnabled then
local char = Player.Character
local Root = char.HumanoidRootPart
if char:FindFirstChild('UpperTorso') then
origc0 = char.UpperTorso:WaitForChild('Waist').C0
end
renderconnec = game:GetService("RunService").Heartbeat:Connect(function(deltaTime)
if char:FindFirstChild('Humanoid') and char.Humanoid.Health > 0 then
local lerpSpeed = 10/(1/deltaTime)
local cframe = CFrame.new(char.UpperTorso.Position, Mouse.Hit.Position)
if char.Humanoid.Sit == false then
local RootPos, MousePos = Root.Position, Mouse.Hit.Position
Root.CFrame = CFrame.new(RootPos, Vector3.new(MousePos.X, RootPos.Y, MousePos.Z))
end
if char:FindFirstChild('UpperTorso') then
local x,y,z = (CFrame.new(char.UpperTorso.Waist.C0.Position) * char.UpperTorso.CFrame:toObjectSpace(cframe)):ToEulerAnglesXYZ()
local cf2 = CFrame.new(char.UpperTorso.Waist.C0.Position) * CFrame.Angles(math.clamp(x,math.rad(-60),math.rad(90)),0,0)
char.UpperTorso.Waist.C0 = char.UpperTorso.Waist.C0:Lerp(cf2,lerpSpeed)
end
else
renderconnec:Disconnect()
end
end)
end
end)
Tool.Unequipped:Connect(function()
if not game.UserInputService.VREnabled then
local char = Player.Character
if renderconnec then
renderconnec:Disconnect()
end
if char and char:FindFirstChild("UpperTorso") then
char.UpperTorso.Waist.C0 = origc0
end
end
end)
I did some testing, and found out that Runservice:BindToRenderStep() got the lowest script activity, with 0.391 at its peak. Second was Runservice.postsimulation with a peak of 0.45. Still, if people know other ways to optimize this script then do tell!
Don’t use findfirstchild so much, you are pretty much calling a function that iterates through the entire character, you can just existence check it and then run the code normally
what do you mean existence check? People in my game can lose their humanoids, so i would need to check whether it exists right? Is there a different way to check whether a player has an uppertorso and humanoid? Or should I just let it error if they are not existent?
No cause th escript would see that it doesn’t exist at the very start and it would return it
Here is the code sample:
local Tool = script.Parent
local Player = game.Players.LocalPlayer
local Mouse = Player:GetMouse()
local origc0 = nil
Tool.Equipped:Connect(function()
if not game.UserInputService.VREnabled then
local char = Player.Character
local Root = char.HumanoidRootPart
local UpperTorso = char.UpperTorso
local Waist = UpperTorso.Waist
local Humanoid = char.Humanoid
origc0 = Waist.C0
renderconnec = game:GetService("RunService").Heartbeat:Connect(function(deltaTime)
if not char:FindFirstChild("UpperTorso") or not char:FindFirstChild("Humanoid") then warn("No humanoid or upper torso. Aborting!") renderconnec:Disconnect() renderconnec = nil return end
if Humanoid.Health > 0 then
local lerpSpeed = 10/(1/deltaTime)
local cframe = CFrame.new(UpperTorso.Position, Mouse.Hit.Position)
if not Humanoid.Sit then
local RootPos, MousePos = Root.Position, Mouse.Hit.Position
Root.CFrame = CFrame.new(RootPos, Vector3.new(MousePos.X, RootPos.Y, MousePos.Z))
end
local x, y, z = (CFrame.new(Waist.C0.Position) * UpperTorso.CFrame:toObjectSpace(cframe)):ToEulerAnglesXYZ()
local cf2 = CFrame.new(Waist.C0.Position) * CFrame.Angles(math.clamp(x, math.rad(-60), math.rad(90)), 0, 0)
Waist.C0 = Waist.C0:Lerp(cf2, lerpSpeed)
else
renderconnec:Disconnect()
end
end)
end
end)
Tool.Unequipped:Connect(function()
if not game.UserInputService.VREnabled then
local char = Player.Character
if renderconnec then
renderconnec:Disconnect()
end
local UpperTorso = char.UpperTorso
local Waist = UpperTorso.Waist
Waist.C0 = origc0
end
end)
I tested this edited version, but it somehow increased the script activity? before with postsimulation it was 2.0% and with ur optimization it is 2.6%?
Implementing your tips also helped reduce the activity, thanks. my equipped function now looks like this:
Tool.Equipped:Connect(function()
if not game.UserInputService.VREnabled then
local char = Player.Character
local Root = char:FindFirstChild('HumanoidRootPart')
local UpperTorso = char:FindFirstChild('UpperTorso')
local Waist = UpperTorso:FindFirstChild('Waist')
local Humanoid = char:FindFirstChild('Humanoid')
if char and UpperTorso and Waist and Humanoid and Root then
origc0 = Waist.C0
renderconnec = game:GetService('RunService').PostSimulation:Connect(function(deltaTime)
if Humanoid.Health > 0 then
local lerpSpeed = 10/(1/deltaTime)
local cframe = CFrame.new(UpperTorso.Position, Mouse.Hit.Position)
if not Humanoid.Sit then
local RootPos, MousePos = Root.Position, Mouse.Hit.Position
Root.CFrame = CFrame.new(RootPos, vector.create(MousePos.X, RootPos.Y, MousePos.Z))
end
local x,y,z = (CFrame.new(Waist.C0.Position) * UpperTorso.CFrame:toObjectSpace(cframe)):ToEulerAnglesXYZ()
local cf2 = CFrame.new(Waist.C0.Position) * CFrame.Angles(math.clamp(x,math.rad(-60),math.rad(90)),0,0)
Waist.C0 = Waist.C0:Lerp(cf2,lerpSpeed)
else
renderconnec:Disconnect()
end
end)
end
end
end)
a new issue might happen if you unequip the tool while alive and equip it again, since that doesnt disconnect when the humanoid is unequipped. that will cause major issue if player equips and unequips tools since it will call the same function multiple times
No that is fine, if you look at the unequipped function in the original script, you can see that it checks whether the connection exists and disconnects it if it does.