Aim Arm Movement Bugged

So I have been trying for a long time to add the part of aiming with your gun into my game, now the problem I have that it does this weird teleporting thing instead of smoothly going towards the position it’s supposed to be at.


Here is the code snippet that sets the so called armOffset:

local ADS_Points = {}
						for i, instance in equippedItemSlot:GetDescendants() do
							if instance:IsA("Attachment") then
								if instance.Name == "ADS_Point" then
									--if currentSight == instance:GetAttribute("Priority") then
										ADS_Points[instance:GetAttribute("Priority")] = instance
										--selectedADS_Point = instance
									--end
								--elseif instance.Name == "ADS_Origin" then
									--ADS_origin = instance
								end
							end
						end
						
						local selectedADS_Point = ADS_Points[currentSight or 1]
						print(selectedADS_Point, ADS_Points)
						if typeof(selectedADS_Point) == "Instance" and selectedADS_Point:IsA("Attachment") then
							if aimLerpConnection then
								aimLerpConnection:Disconnect()
							end
							
							local startTime = tick()
							aimLerpConnection = RunService.RenderStepped:Connect(function(deltaTime)
								--+ Vector3.new(0, 1.5, 0.625)
								--print((tick() - startTime) * (1 / zoomTime), zoomTime)
								local selectedADS_Point = ADS_Points[currentSight or 1]
								armOffset = (humanoidRootPart.CFrame * CFrame.new(0, 0.5, 0)).Position:Lerp((humanoidRootPart.CFrame * CFrame.new(0, 1.5, 0.625)).Position - selectedADS_Point.WorldPosition, math.clamp((tick() - startTime) * (1 / zoomTime), 0, 1))
								--armOffsetL = ADS_origin.WorldPosition:Lerp(ADS_origin.WorldPosition - selectedADS_Point.WorldPosition, math.clamp((tick() - startTime) * (1 / zoomTime), 0, 1))
								--armOffsetR = ADS_origin.WorldPosition:Lerp(ADS_origin.WorldPosition - selectedADS_Point.WorldPosition, math.clamp((tick() - startTime) * (1 / zoomTime), 0, 1))
								
								armRotation = Vector3.new() --humanoidRootPart.Rotation:Lerp(humanoidRootPart.Rotation - selectedADS_Point.WorldOrientation, math.clamp((tick() - startTime) * (1 / zoomTime), 0, 1))
								--armRotationL = ADS_origin.WorldRotation:Lerp(ADS_origin.WorldRotation - selectedADS_Point.WorldOrientation, math.clamp((tick() - startTime) * (1 / zoomTime), 0, 1))
								--armRotationR = ADS_origin.WorldRotation:Lerp(ADS_origin.WorldRotation - selectedADS_Point.WorldOrientation, math.clamp((tick() - startTime) * (1 / zoomTime), 0, 1))
							end)
						end

And here is the function that sets the C0 and C1 of the arm joints (I had purposefully changed the lookAtPosition)

function updateCharacterRotation(character : Model, lookAtPosition : CFrame, allRotationAxis : boolean?)
	if typeof(character) == "Instance" and character:IsA("Model") then
		local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
		local torso = character:FindFirstChild("Torso")
		local head = character:FindFirstChild("Head")
		local humanoid = character:FindFirstChildOfClass("Humanoid")

		if typeof(torso) == "Instance" and torso:IsA("BasePart") and typeof(head) == "Instance" and head:IsA("BasePart") and typeof(humanoidRootPart) == "Instance" and humanoidRootPart:IsA("BasePart") and typeof(humanoid) == "Instance" and humanoid:IsA("Humanoid") then
			local leftarm = character:FindFirstChild("Left Arm")
			local rightarm = character:FindFirstChild("Right Arm")

			local leftshoulder = torso:FindFirstChild("Left Shoulder")
			local rightshoulder = torso:FindFirstChild("Right Shoulder")
			local neck = torso:FindFirstChild("Neck")
			
			lookAtPosition = humanoidRootPart.CFrame * CFrame.new(0, 1.5, -1000)
			local CameraDirection = humanoidRootPart.CFrame:ToObjectSpace(lookAtPosition).LookVector
			if typeof(neck) == "Instance" and neck:IsA("Motor6D") then
				local new_c0 = CFrame.new(neck.C0.Position) * CFrame.Angles(3 * math.pi/2, 0, math.pi) --[[* CFrame.Angles(0, 0, -math.asin(CameraDirection.x))]] * CFrame.Angles(-math.asin(CameraDirection.y), 0, 0)
				
				TweenService:Create(neck, TweenInfo.new(0.1, Enum.EasingStyle.Quad, Enum.EasingDirection.Out, 0, false, 0), {C0 = new_c0}):Play()
			end
			
			local cameraDirection = Vector3.new() --(humanoidRootPart.CFrame * CFrame.new(0, 1, 0) * CFrame.new(humanoid.CameraOffset)).LookVector
			if typeof(leftarm) == "Instance" and leftarm:IsA("BasePart") and typeof(leftshoulder) == "Instance" and leftshoulder:IsA("Motor6D") then
				local lookat = CFrame.lookAt(humanoidRootPart.Position + Vector3.new(0, 1.5, 0) + armOffset, lookAtPosition.Position + cameraDirection) --* CFrame.new(humanoid.CameraOffset)
				--local startCFrame = CFrame.new(lookat.Position) --* CFrame.Angles(math.rad(lookat.Rotation.X), math.rad(lookat.Rotation.Y), math.rad(lookat.Rotation.Z))
				--lookat = CFrame.new(lookat.Position) * CFrame.Angles(math.rad(humanoidRootPart.Rotation.X), math.rad(humanoidRootPart.Rotation.Y), math.rad(humanoidRootPart.Rotation.Z)) * CFrame.Angles(math.rad(math.clamp(lookat.Rotation.X, -90, 90)), 0, 0)
				
				local cfrm = lookat --[[head.CFrame]] * CFrame.new(-1.5, -1.5, 0) * CFrame.new(0.5, 0.5, 0) * CFrame.Angles(math.rad(armRotation.X), math.rad(armRotation.Y + -90), math.rad(armRotation.Z)) --* CFrame.new(0, 0, -0.625)
				local toCFrame = humanoidRootPart.CFrame:ToObjectSpace(cfrm) --* head.CFrame:ToObjectSpace(CFrame.new(armOffset) * CFrame.Angles(math.rad(armRotation.X), math.rad(armRotation.Y), math.rad(armRotation.Z)))
				--local armCFrame = CFrame.new(armOffset) * CFrame.Angles(math.rad(armRotation.X), math.rad(armRotation.Y), math.rad(armRotation.Z))
				local new_c0 = toCFrame --CFrame.new(armOffset + toCFrame.Position) * CFrame.Angles(math.rad(armRotation.X + toCFrame.Rotation.X), math.rad(armRotation.Y + toCFrame.Rotation.Y), math.rad(armRotation.Z + toCFrame.Rotation.Z)) -- * CFrame.new(0, 0, -0.625)
				
				leftshoulder.C0 = new_c0
				--TweenService:Create(leftshoulder, TweenInfo.new(0.1, Enum.EasingStyle.Quad, Enum.EasingDirection.Out, 0, false, 0), {C0 = new_c0}):Play()
				--leftshoulder.C0 = new_c0
			end

			if typeof(rightarm) == "Instance" and rightarm:IsA("BasePart") and typeof(rightshoulder) == "Instance" and rightshoulder:IsA("Motor6D") then
				local lookat = CFrame.lookAt(humanoidRootPart.Position + Vector3.new(0, 1.5, 0) + armOffset, lookAtPosition.Position + cameraDirection) --* CFrame.new(humanoid.CameraOffset)
				--local startCFrame = CFrame.new(lookat.Position) --* CFrame.Angles(math.rad(lookat.Rotation.X), math.rad(lookat.Rotation.Y), math.rad(lookat.Rotation.Z))
				--lookat = CFrame.new(lookat.Position) * CFrame.Angles(math.rad(humanoidRootPart.Rotation.X), math.rad(humanoidRootPart.Rotation.Y), math.rad(humanoidRootPart.Rotation.Z)) * CFrame.Angles(math.rad(math.clamp(lookat.Rotation.X, -90, 90)), 0, 0)
				
				local cfrm = lookat --[[head.CFrame]] * CFrame.new(1.5, -1.5, 0) * CFrame.new(-0.5, 0.5, 0) * CFrame.Angles(math.rad(armRotation.X), math.rad(armRotation.Y + 90), math.rad(armRotation.Z)) --* CFrame.new(0, 0, -0.625)
				local toCFrame = humanoidRootPart.CFrame:ToObjectSpace(cfrm) --* head.CFrame:ToObjectSpace(CFrame.new(armOffset) * CFrame.Angles(math.rad(armRotation.X), math.rad(armRotation.Y), math.rad(armRotation.Z)))
				--local armCFrame = CFrame.new(armOffset) * CFrame.Angles(math.rad(armRotation.X), math.rad(armRotation.Y), math.rad(armRotation.Z))
				local new_c0 = toCFrame --CFrame.new(armOffset + toCFrame.Position) * CFrame.Angles(math.rad(armRotation.X + toCFrame.Rotation.X), math.rad(armRotation.Y + toCFrame.Rotation.Y), math.rad(armRotation.Z + toCFrame.Rotation.Z)) -- * CFrame.new(0, 0, -0.625)
				--armOffset
				rightshoulder.C0 = new_c0
				--TweenService:Create(rightshoulder, TweenInfo.new(0.1, Enum.EasingStyle.Quad, Enum.EasingDirection.Out, 0, false, 0), {C0 = new_c0}):Play()
				--rightshoulder.C0 = new_c0
			end
		end
	end
end

And yes, I’m using the actual arms of the player character and no I’m not gonna use a viewmodel, you can’t convince me to do so.

Oh yeah and the attachments being so weirdly positioned doesn’t matter, I can fix that later.

1 Like

One probably unimportant fix im gonna do is change it from humanoidRootPart.Position:Lerp() to Vector3.new():Lerp()

You have run service running indefinitely. When the position is right, use :Disconnect to stop the repetitive movement

In this case aimLerpConnection:Disconnect

But why does it snap like that tho. I also disconnect it when the player stops aiming or rather stops holding the right mouse button.

Easiest start would be to test if aidLerpConnection is still running, put print() or warn() inside the loop and look out for that print() or warn() in output. This is the best start to debug this.

Ive already done that, could it have something to do with the alphaTime surpassing 1? The armOffset also goes to vector3.new(0,0,0) when stoppint aiming, I couldnt upload a longer video bc of the file size being bigger than roblox allows

How is the functions called? Are you using UserInputService, localplayer:GetMouse(), or something else?

UserInputService.InputBegan

I cant access the full code as of right now because I’m not at home so it’s more of a out of my head thing but everythimg I said so far was like it was in the code

The armLerp connection is also a “public” local variable, not sure if that helps tho.

Have you tried using debounce in UserInputService.InputBegan?

What do you mean? What would that even do tho?

local toolEquipped = true -- example
local debounce = false
UIS.InputBegan:Connect(function(input, gameProcessed)
  if input.UserInputType == Enum.UserInputType.MouseButton2 and toolEquipped then
    debounce = true
    ...
  end
end)

I mean something like this. This could probably prevent the repetetave call for zoom function.

Im pretty sure that wouldnt be the problem tho, I can try but I don’t think that’s the problem, probably has something to do with WorldToObjectSpace or something like that.

Like I (think I) said, I’m not at home and can’t test anything right now.

The debounce did nothing but changing it to Vector3.new(0,0,0) did massively reduce the seizure thing but it still does that.

I still think this is something to do with loop somewhere. If lowering vector reduced it, looping would make sense.

Yeah but I can’t disconnwct it because if I do, the arms would probably have not the right offset when I, for example, look upwards. I had “disabled” the arm tracking for the example video.