How would I be able to get this script run smoother?

Inside of my gun script I have a code in it that makes your arms move up and down with the mouse. It seems to work fine, but then all of a sudden it stopped letting me fire the gun itself.

I previously fixed it before by using > RenderStepped However, now it doesn’t shoot. I had fixed it by breaking the loop, but now Its really choppy again.

I’ve tried re positioning the script, but it just breaks everything below it if I do not break the loop.

Here is the code: (The code that resets the character when you unequipped the weapon is working fine.)

local function UpdateCharMovement()
while RenderStepped:Wait() do
if Equipped then
	
local Neck = Character:FindFirstChild("Neck", true)
local Arm = Character:FindFirstChild("Right Shoulder", true)
local LeftArm = Character:FindFirstChild("Left Shoulder", true)
local dir = (Mouse.Hit.p - Character.Head.Position).Unit
local angle = math.acos(dir:Dot(Vector3.new(0, 1, 0))) - math.pi/2
	angle = math.min(math.max(- math.pi/5, angle), math.pi/5)
	Neck.C0 = CFrame.Angles(- angle + math.pi/2, math.pi, 0) + Vector3.new(0, Neck.C0.Y, 0)
	
	Arm.C0 = CFrame.Angles(- angle, math.pi/2 + math.pi/40 + math.pi/32, math.pi/36) + Vector3.new(Arm.C0.X, Arm.C0.Y, Arm.C0.Z)
	
	LeftArm.C0 = CFrame.Angles(- angle, -math.pi/2 - math.pi/40, -math.pi/36) + Vector3.new(LeftArm.C0.X, LeftArm.C0.Y, LeftArm.C0.Z)

	break

		end
	end
end
1 Like
local function UpdateCharMovement()
while Equipped do
RenderStepped:Wait()
local Neck = Character:FindFirstChild("Neck", true)
local Arm = Character:FindFirstChild("Right Shoulder", true)
local LeftArm = Character:FindFirstChild("Left Shoulder", true)
local dir = (Mouse.Hit.p - Character.Head.Position).Unit
local angle = math.acos(dir:Dot(Vector3.new(0, 1, 0))) - math.pi/2
	angle = math.min(math.max(- math.pi/5, angle), math.pi/5)
	Neck.C0 = CFrame.Angles(- angle + math.pi/2, math.pi, 0) + Vector3.new(0, Neck.C0.Y, 0)
	
	Arm.C0 = CFrame.Angles(- angle, math.pi/2 + math.pi/40 + math.pi/32, math.pi/36) + Vector3.new(Arm.C0.X, Arm.C0.Y, Arm.C0.Z)
	
	LeftArm.C0 = CFrame.Angles(- angle, -math.pi/2 - math.pi/40, -math.pi/36) + Vector3.new(LeftArm.C0.X, LeftArm.C0.Y, LeftArm.C0.Z)
end
end

This may or may not fix your problem, I edited your code a bit.

2 Likes

There can be some error checking added after the FindFirstChild calls here, in case any one of them returns nil. I’d also suggest storing the results of the FindFirstChild calls above/outside the loop. There’s no need to repeatedly do the operation in every iteration of the loop, especially with the recursive option. See a note from the wiki:

FindFirstChild takes about 20% longer than using dot operator, and almost 8 times longer than simply storing a reference to an object. Therefore, you should avoid calling FindFirstChild in performance dependent code, such as in tight loops or functions connected to RunService.Heartbeat/RunService.RenderStepped

1 Like

That’s true, wasn’t looking at that actually. All those variables can be stored outside of the function’s scope.

1 Like

I did just do that, however it still is choppy, and when I remove the break its fixed, but then the gun doesn’t work.

1 Like

Did you try the code I gave you?

Yes, it actually was the code I used previously. Then I changed it because it didn’t work

1 Like

I wrote it again in a different way, I noticed all that was in the function was a loop, we can actually turn that into a function binded to a RenderStep event, so you could try something like this for example:

1 Like

My previous comment was just a little touch up on the code provided by @C_Sharper. Regarding your issue, it’s hard to tell without knowing the full code, but may be something with the while loop yielding your whole script. Maybe try spawning it in a new thread.

1 Like

I’m going to use my magic powers and guess that you’re calling UpdateCharMovement inside of another loop, one which runs your shooting code? That’s probably why the break is helping, because it’s half-fixing the error you made by calling this in a loop.

What you probably want is to not have any loop at all in it if you’re already calling it from a loop, or use an entirely separate loop / connection for the arm animation like @C_Shader’s BindToRenderStep solution.

1 Like

Edit: Found out that @C_Sharper’s post worked. Thanks guys!

2 Likes